Python网络爬虫快速上手2(解析json数据,超详细)!
环境准备:
按照上篇安装requests-html的步骤安装requests库
通过html请求
实例内容:
从网页图片中爬图片的链接并下载
实例背景:
从百度图片(https://image.baidu.com)中下载自己想要类型的图片,张数,尺寸。
导入requests和json库
import requests import json
-获取得到图片信息的请求链接:
打开网页(https://image.baidu.com)搜索“壁纸”
- 任意位置右键检查
- 网络
- 点击HTML和XHR(我们要到ajax请求的json数据,里面包含图片信息)
- 鼠标下滑图片页面会出现获取图片的请求,点击发现有一个GET请求返回了一大堆json数据,这些数据包含有30张图片的信息,如下图所示:
- 点击一条复制GET中的链接
- 分析链接:
链接返回的内容
''' 缩减后的链接: https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&width=&height=&word=王者荣耀&pn=30 tn=resultjson_com 固定 ipn=rj 固定的 width= 图片宽度(为空获取全部宽度的图片) height= 同上 word= 要搜索图片类型的关键字 pn= 假如把服务器上的所有符合要求的图片都放在一个数组里,那pn相当于一个下标,从pn开始获取往后30图片信息 width,height,pn删了不影响网页,但是保留话会好点,(灵活分析,不好说)
复制网页的全部内容,浏览器搜索json在线解析,粘贴格式化,继续分析。。。
- 分析完下一步就要用到啦!!!
- 获取(n张)图片链接
for i in range(30): imgUrl = jsonData['data'][i]['thumbURL'] imgList.append(imgUrl) if len(imgList) >= num: break
- 每次请求得30张图片所以循环30次,超过30张会在次请求(所以到这里要再外层加多一个循环)
- 下一句是爬图片了,刚刚分析了列表data第i张图片信息下的thubURL就是图片链接。
- 在爬图片之前我们要把请求headers伪装成浏览器的请求
headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0" } 1234
def GetImgUrl(title,num,width='',height=''): global headers imgList = list() index = 0 while True: url = "https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&width=" + str(width) + \ "&height=" + str(height) + "&word=" + title + "&pn=" + str(index) data = requests.get(url, headers=headers) jsonData = json.loads(data.content.decode('utf-8')) for i in range(30): imgUrl = jsonData['data'][i]['thumbURL'] imgList.append(imgUrl) if len(imgList) >= num: break if len(imgList) >= num: break index = index + 30 return imgList
然后按照思路代码补到合适的位置上:
- 伪装好headers,用get请求url(网页)
- 加载json数据,用utf-8编码
- 写循环获得图片链接,imgURL得到一张图片的链接,把它放到(append方法)链表里(imgList),所以在上面创建一个链表来存放
- 链表长度等于我们要的图片个数就退出循环(少于30张的时候),大于30张要再次请求,所以外面要加一个whlie循环
- 下载功能单独封装成一个方法,global headers表示可以引用headers这个全局变量。
- 得到图片链接就可以下载了
def DownloadImg(urlList): index=0 for i in urlList: with open(str(index)+i[-4:],'wb') as img: print(str(index)+i[-4:]) f=requests.get(i,headers=headers) img.write(f.content) img.close() index=index+1
- 自定义一个下载的方法
- 遍历图片链接
- 打开文件,图片名字index+每条链接的后面4位,as(别名)
- 输出
- 请求下一条链接
- 写入img中 (图片就下载了)
- 记得关闭文件
- index不变的话文件名就会相同就会被盖,这样只能的最后一张图片,index++就不会被覆盖啦!!!
- 用到的库要记得加上
import requests import json 12
- 最后就是调用了
if __name__ == "__main__": urlList=GetImgUrl("小清新",88) DownloadImg(urlList) 1234
完整代码
''' 缩减后的链接: https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&width=&height=&word=王者荣耀&pn=60 tn=resultjson_com 固定 ipn=rj 固定的 width= 图片宽度(为空获取全部宽度的图片) height= 同上 word= 要搜索图片类型的关键字 pn= 假如把服务器上的所有符合要求的图片都放在一个数组里,那pn相当于一个下标,从pn开始获取往后30图片信息 ''' import requests import json headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0" } def DownloadImg(urlList): index=0 for i in urlList: with open(str(index)+i[-4:],'wb') as img: print(str(index)+i[-4:]) f=requests.get(i,headers=headers) img.write(f.content) img.close() index=index+1 def GetImgUrl(title,num,width='',height=''): global headers imgList = list() index = 0 while True: url = "https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&width=" + str(width) + \ "&height=" + str(height) + "&word=" + title + "&pn=" + str(index) data = requests.get(url, headers=headers) jsonData = json.loads(data.content.decode('utf-8')) for i in range(30): imgUrl = jsonData['data'][i]['thumbURL'] imgList.append(imgUrl) if len(imgList) >= num: break if len(imgList) >= num: break index = index + 30 return imgList if __name__ == "__main__": urlList=GetImgUrl("小清新",88) DownloadImg(urlList)
完整项目代码获取点这里