python爬取百度图片
案例目的:
通过爬取百度图片,介绍如何破解url中的加密数据,以及在搜索不同内容时如何格式化输出不同的url。
代码功能:
输入要搜索的内容,输入要爬取的页数,自动将每一页对应的图片下载到本地。
1.找到主页对应的url
注:这里说明如何找到我们需要的url。我们在百度图片得到搜索结果后,得到的页面为动态数据(通过滑轮得到更多的数据,即通过滑轮发送更多的请求),因此我们可以在XHR中寻找,XHR对应的一般为动态数据。
2.检查响应数据(图片的url)
3.对图片的url发送请求,获取响应
响应数据为每页对应的图片
4.将图片保存到本地:
注:图片数量比较多,因此为了避免重复,我们将表情包+时间戳作为图片的名称。
5.(重点部分)找到不同页以及不同内容对应url的规律:
通过对比不同页以及搜索不同内容的url:
关键词为"钢铁侠"前两页的url:
关键词为"蜘蛛侠"前两页的url:
对比以上url可知:
不同页的url对应不同的参数:
参数一:pn
参数二:gsm
参数三:最后"="前面的数字
不同搜索内容url对应不同的参数:
参数一:queryWord
参数二:word
参数分析:
一:不同页参数的url:
1.参数一pn:第一页的pn参数为30,第二页为60,第三页为90,因此pn参数的规律为页数n*30。
2.参数二gsm:经过分析发现,gsm参数为参数pn的16进制数。
3.参数三:根据参数的格式可知,为以毫秒为单位的时间戳。
二:不同搜索内容url对应的参数:
参数一queryWord:搜索内容对应的编码格式
参数二word:同上
6.将参数格式化放在url中:
7.找到url图片对应的jsonpath语法:
通过json在线解析,找到图片url的jsonpath语法。$.data[*].middleURL
解析完毕,上代码:
import requests
import time
import jsonpath
if __name__ == '__main__':
content = input('请输入要搜索的内容:')
pages = int(input('请输入要爬取的页数:'))
for i in range(pages):
pn = (i+1)*30
# 确认图片页面的url
url = f'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord={content}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=©right=&word={content}&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&force=&pn={pn}&rn=30&gsm={str(hex(pn))[-2:]}&{str(int(time.time())*1000)}='
# 创建请求头参数
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
}
# 发送请求获取响应
response = requests.get(url,headers=headers)
# 判断数据类型(为json类型)
py_data = response.json()
# 提取数据中图片的url
img_url = jsonpath.jsonpath(py_data,'$.data[*].middleURL')
print(len(img_url))
for i in py_data['data']:
if i:
img_url = i['middleURL']
response1 = requests.get(img_url,headers=headers)
bytes_data = response1.content
# 保存数据
with open(f'{content}.{int(time.time()*1000)}.jpg','wb')as f:
f.write(bytes_data)
搜索内容:钢铁侠;页数:两页