以豆瓣图片搜索“迪丽热巴”为例,在开发者模式下的 Network 找到名为 search_photo 的 XHR 文件,复制源网址打开。
可以看到一共有 8315 个搜索结果,从 0 开始(start=0),每页展示 20 个,和网址的 “limit=20” 一致,可以通过修改 limit 的属性值来展示每页显示的图片数量,修改 start 的值来跳转到不同页面。各个图片的链接则在 src 内。这样我们就已经获取到了源网址,可以爬取所有图片的链接。
base_url = 'https://www.douban.com/j/search_photo?q=%E8%BF%AA%E4%B8%BD%E7%83%AD%E5%B7%B4&limit=40&start={}'
for i in range(0,8320,40):
#分页链接
url = base_url.format(i)
resp = requests.get(url,headers=headers).text
text = json.loads(resp,encoding='utf-8')
for image in text['images']:
#图片网址中的thumb代表下载下来的是小图片,将其替换为l下载大图片
image['src'] = re.sub(r'thumb',r'l',image['src'])
通过以上代码获得了所有图片的链接。因为图片链接中有 thumb,获取的图片会是小图片,我们将它替换为 l 来获取相对较大的图片。接下去是为图片创建文件路径和写入。
dir = 'C:/Users/春风沐古/Desktop/no_code_1/'+str(image['id'])+'.jpg'
try:
#爬取图片
resp = requests.get(src,headers=headers,timeout=10)
#打开图片文件
f = open(dir,'wb')
#将爬取的内容写入图片文件
f.write(resp.content)
#关闭文件
f.close()
#防止读取超时和连接未知服务器报错
except (requests.exceptions.ConnectionError,requests.exceptions.ReadTimeout):
print('无法下载图片')
为了防止连接未知服务器和读取超时报错,我们使用 try…except 语句来执行图片的下载。然后就是将代码用函数封装起来,方便复用,完整的代码如下:
import requests
import json
import re
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
#下载图片
def download_pic(src,id):
#图片路径
dir = 'C:/Users/春风沐古/Desktop/no_code_1/'+str(id)+'.jpg'
try:
#爬取图片
resp = requests.get(src,headers=headers,timeout=10)
#打开图片文件
f = open(dir,'wb')
#将爬取的内容写入图片文件
f.write(resp.content)
#关闭文件
f.close()
#防止读取超时和连接未知服务器报错
except (requests.exceptions.ConnectionError,requests.exceptions.ReadTimeout):
print('无法下载图片')
#主函数
def main():
base_url = 'https://www.douban.com/j/search_photo?q=%E8%BF%AA%E4%B8%BD%E7%83%AD%E5%B7%B4&limit=40&start={}'
#一共有8000多张图片,循环获取图片
for i in range(0,8320,40):
url = base_url.format(i)
resp = requests.get(url,headers=headers).text
text = json.loads(resp,encoding='utf-8')
for image in text['images']:
#图片网址中的thumb代表下载下来的是小图片,将其替换为l下载大图片
image['src'] = re.sub(r'thumb',r'l',image['src'])
#打印图片网址
print(image['src'])
download_pic(image['src'],image['id'])
if __name__ == '__main__':
main()
一般来说这种方法基本已经满足下载的需求,对于爬取的速度进行了 10 秒(timeout=10)的等待限制,以免网站反爬虫限制,更好的防反爬虫可以完善请求头和用代理以及增加随机性。