本篇是python爬虫之 爬取案例网页ajax请求数据2之一 跳转url下载图片_水w的博客-CSDN后续补充博客。
在前面的基础上,我们爬到了第一个ajax请求我们想爬的东西logo生成url地址,接下来我想爬所有后续的地址ajax请求我们想爬的东西logo生成url并下载这些图片。
思路和步骤:
此外,我们通过这些定期的变化来改变参数,然后模拟用户点击加载更多的操作,爬行更多logo图片。
然后我们开始在上一篇文章章写的代码。
(1)创建一个LogoSpider之后我们先分析一下这个项目,分析主要需要哪些函数,每个函数需要实现哪些功能。
class LogoSpider(): def __init__(self): self.version = '' def get_json(self,page): """拿到ajax请求的保存logo图片信息的json""" pass def save_img(self,image_id, image_url): """保存图片""" pass def main(self,page): """主函数""" pass
(2)创建号类和分析函数功能后,我们开始编写代码。
首先先编写get_json()函数,功能是获得ajax请求的logo图片信息的json。
在这个函数中,我们现在需要多少次?ajax区分请求,因为如果不是第一次ajax要求的时候,会比第一次好。ajax请求不仅page参数变化,多了一个参数version。
根据相应的第几次,我们需要ajax请求,来改变我们的请求参数params。
ajax请求的logo图片信息的json格式数据,如图所示:
get_json()函数代码:
def get_json(self,page): """拿到ajax请求的保存logo图片信息的json""" if page == 1: params = { "brandName": "小天才", "slogan": "Genius", "keywords": "互联网", "industryName": "软件和信息技术服务业", "industryId": 49, "sceneId": 2, "page": 1, } else: # 之后的ajax请求变更参数:page ,version params = { "brandName": "小天才", "slogan": "Genius", "keywords": "互联网", "industryName": "软件和信息技术服务业", "industryId": 49, "sceneId": 2, "page": page, "version":self.version, } # 拼接参数 url = base_url urlencode(params) try: response = requests.get(url,headers=headers) if response.status_code==200: return response.json() except requests.ConnectionError as e: print("Error",e.args)
(2)编写save_img()函数的主要功能是通过请求分析的每个函数logo图片的url,来获取到logo将图片保存到文件夹中。
在这个函数中,调用了全局变量sum_success,用来记录下载了多少图片。
save_img()函数代码:
def save_img(self,image_id, image_url): """通过请求分析的每一个logo图片的url,来获取到logo将图片保存到文件夹中。""" global sum_success print正在下载image_id为',image_id) try: if not os.path.exists(IMAGE_SRC): os.mkdir(IMAGE_SRC) filename = IMAGE_SRC image_id '.jpg' #如果图片已经存在,跳过这个循环 if not os.path.exists(filename): # 下载图片并保存在文件夹中 urllib.request.urlretrieve(image_url, filename=filename) print('*******图片image_id为' str(image_id) 下载完成 sum_success = 1 else: print('**********这张图片已存在‘) except IOError as e: print保存图片出现异常失败!', e)
(3)编写main()函数的主要功能是get_json()获得函数json格式数据,处理和分析数据,生成页面logo图片的url每次从队列中取出一个url,调用save_img()函数保存logo图片到文件夹。
主要功能如下:
1.从get_json()获得函数json格式数据;
2.处理和分析数据;
3.生成页面logo图片的url保存在队列中;
4.每次从队列中取出一个url,调用save_img()函数保存logo图片到文件夹。
补充知识:
1、queue标准库
from queue import Queue data_queue = Queue() # 创建队列 data_queue.qsize() # 队列大小 data_queue.put(10) # 将10入队 data_queue.get() # 出队操作,并返回队首元素 data_queue.empty() # 判断队列是否为空
2、os.path.exists()函数:
os.path该模块主要用于获取文件的属性,因此该函数的功能是判断文件是否存在。
os.path.exists([文件路径])
如果返回False,那么说明以该文件名命名的文件当前不存在,需要使用os.mkdir()函数以此文件名创建新文件。
3、urllib.request.urlretrieve()函数:
利用urlretrieve()函数可以将数据下载到本地。
参数:
- url:需要request请求的url地址(即需要获取数据的地址)
在本篇中,url为每一个logo图片的url - filename:存储请求获得的数据的文件名
在本篇中,filename为“IMAGE_SRC image_id '.jpg'”
-reporthook:这是一个回调函数,当连接到服务器和相应的数据块传输时,我们可以使用这个回调函数来显示当前的下载进度
-data:指post该方法返回包含两个元素的服务器数据(filename, headers) 元组,filename 表示保存到当地的路径,header表示服务器的响应头
使用方法:
urllib.request.urltrieve(url,filename=None,reporthook=None,data=None)
main()函数代码:
def main(self,page):
""" 1.从get_json()函数拿到获取的json格式数据
2.对数据进行处理和解析
3.将页面生成的logo图片的url保存到队列中
4.从队列中每次取出一个url,调用save_img()函数保存logo图片到文件夹
"""
j = self.get_json(page)
# print(j)
try:
# 得到下一个ajax请求的version参数
self.version = j['data']['images']['version']
print('version:',self.version)
# 将每一个logo图片的url和id数据解析出来,并以字典格式放入队列中保存
for goods in j['data']['images']['list']:
# print({'id':goods['goodsId'],'url':goods['url']})
data_queue.put({"id":goods['goodsId'],"url":goods['url']})
global sum_success
# 当队列为空时,才停止
while data_queue.empty() != True:
# 从队列中取出一个图片信息的字典格式
image = data_queue.get()
self.save_img(image_id=image['id'],image_url=image['url'])
print(">>>>>>>>>>>>>>>已有"+ str(sum_success) +"个下载成功")
time.sleep(1)
else:
print("data_queue队列为空!")
except Exception as err:
print('出现异常:',err)
(4)完整代码:
from ensurepip import version
from urllib.parse import urlencode
from pyquery import PyQuery as pq
from bs4 import BeautifulSoup
import re,bs4,json,socket,random,os,requests,threading,time,urllib
from queue import Queue
base_url = "https://logo.aliyun.com/logo/buildGoodsList.json?"
headers = {
"cookie": "cna=liaPF6GPZ0cCAXuuxE6TaBwc; aliyun_choice=CN; _uab_collina=165174083869593284740835; t=c68c60f79656b6361d4c3299eceefb0d; login_aliyunid_pk=1934551737570629; userViewed=aliyun745882****; aliyun_lang=zh; XSRF-TOKEN=1972b755-e958-4330-86e7-3777d4ab992d; _samesite_flag_=true; cookie2=1da4afe997cab48cc14db3f3c107e487; _tb_token_=e345333e7a7e3; _hvn_login=6; csg=e7a351ed; login_aliyunid=\"aliyun745882****\"; login_aliyunid_ticket=XXZQg4KFWufyvpeV*0*Cm58slMT1tJw3_p$$_29heKupjCAXonKn8srwMrwdWdmdfARMiNcYT7KgxVof_BNpwU_TOTNChZBoeM1KJexdfb9zhYnsN5Zos6qISCrRt7mGxbigG2Cd4fWaCmBZHIzsgd6q0; login_aliyunid_csrf=_csrf_tk_1567151892930436; hssid=1R5BQXbbgg6ZI2G5RDYuPlQ1; hsite=6; aliyun_country=CN; aliyun_site=CN; JSESSIONID=B2DD0AEF589EBA595F400F5B4BC1A34F; isg=BLOzZloi1S8TaJmg6Uvv2hRxQrfd6EeqrRu0HWVQD1IJZNMG7bjX-hH1H5SKEZ-i; l=eBN9iCerLSmJGNcKBOfahurza77OSIRvWuPzaNbMiOCPOV5B5sqfW645E5T6C3hVh68HR3Jfz-p8BeYBqQd-nxv96aiE7Vkmn; tfstk=c3zPBbTpSaQykF0CX4gFdNR7DRPRZ0HnCElZqOvgx4W1DXoliIvKixQtgXR2K0f..",
"referer": "https://logo.aliyun.com/logo?msctype=email&mscareaid=cn&mscsiteid=cn&mscmsgid=9140122032200691186&spm=a2c4l.26849360.zh-cnc.1&accounttraceid=76ef6c44de72465daef048c81127602enspq",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
}
# 存储图片的位置 D:\大学\实习方面\BaiduSpider\LogoSpider\logo
IMAGE_SRC = 'D://大学/实习方面/BaiduSpider/LogoSpider/logo/'
# 使用队列保存存放图片的id和url地址, 确保线程同步
data_queue = Queue()
sum_success = 0
sum_failed = 0
class LogoSpider():
def __init__(self):
self.version = ''
def get_json(self,page):
"""拿到ajax请求的保存logo图片信息的json"""
if page == 1:
params = {
"brandName": "小天才",
"slogan": "Genius",
"keywords": "互联网",
"industryName": "软件和信息技术服务业",
"industryId": 49,
"sceneId": 2,
"page": 1,
}
else:
# 之后的ajax请求变化的参数:page++,version
params = {
"brandName": "小天才",
"slogan": "Genius",
"keywords": "互联网",
"industryName": "软件和信息技术服务业",
"industryId": 49,
"sceneId": 2,
"page": page,
"version":self.version,
}
# 拼接参数
url = base_url + urlencode(params)
try:
response = requests.get(url,headers=headers)
if response.status_code==200:
return response.json()
except requests.ConnectionError as e:
print("Error",e.args)
def save_img(self,image_id, image_url):
"""保存图片"""
global sum_success
print('正在下载image_id为',image_id)
try:
if not os.path.exists(IMAGE_SRC):
os.mkdir(IMAGE_SRC)
filename = IMAGE_SRC + image_id + '.jpg'
#如果图片已经存在了,跳过本次循环
if not os.path.exists(filename):
# 下载图片,并保存到文件夹中
urllib.request.urlretrieve(image_url, filename=filename)
print('*******图片image_id为' + str(image_id) + '下载完成')
sum_success += 1
else:
print('**********此图片已存在')
except IOError as e:
print('保存图片出现异常失败!', e)
def main(self,page):
j = self.get_json(page)
# print(j)
try:
# 得到下一个ajax请求的version参数
self.version = j['data']['images']['version']
print('version:',self.version)
# 将每一个logo图片的url和id数据解析出来,并以字典格式放入队列中保存
for goods in j['data']['images']['list']:
# print({'id':goods['goodsId'],'url':goods['url']})
data_queue.put({"id":goods['goodsId'],"url":goods['url']})
global sum_success
# 当队列为空时,才停止
while data_queue.empty() != True:
# 从队列中取出一个图片信息的字典格式
image = data_queue.get()
self.save_img(image_id=image['id'],image_url=image['url'])
print(">>>>>>>>>>>>>>>已有"+ str(sum_success) +"个下载成功")
time.sleep(1)
else:
print("data_queue队列为空!")
except Exception as err:
print('出现异常:',err)
if __name__ == '__main__':
logospider = LogoSpider()
page = 3 # 起始ajax请求数
logospider.version = '这块儿写爬取到的version'
# 对前3个ajax请求进行爬取
while page<= 6:
logospider.main(page)
page += 1
在vscode新建终端,在终端输入命令执行代码:
python spide.py
(5)vscode的终端显示这张图片已经成功下载了,具体的生成结果如下:
一共发送了4次ajax请求,下载了108张图片(这里截图不完整)
我们随便打开一张图片,如下图所示:
OK,那么我们今天就到这里了!!