环境准备:
按照上篇安装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"
}
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
- 最后就是调用了
if __name__ == "__main__":
urlList=GetImgUrl("小清新",88)
DownloadImg(urlList)
完整代码
'''
缩减后的链接:
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)
未完待续!!!
通过解析HTML
通过解析html
自动化