今天帮别人写一个爬虫,爬豆瓣中的剧照,爬虫的部分并不难写,我通过解析拿到了最终的图片URL,当我用谷歌浏览器去分析他的请求头的时候,发现了这样的情况:
有两个坑吧,第一个是这个图片的格式是webp,如果直接右键存储或者直接用代码存储的话,这张图片就只能从浏览器中打开了,不过这个问题比较好解决,只需要利用PIL.Image重新导出成jpg就可以了:
# 下载图片
res = requests.get(url,headers = picHead);
# 打开文件
f = io.BytesIO(res.content);
# 打开图片
im = Image.open(f)
# 加载图片
im.load();
# 存储图片
im.save('./temp.jpg');
麻烦的地方在获取图片上,他的属性里面是有冒号的,当时没有多想,于是有下面的写法:
# 下载图片
def downloadPic1(url):
# 读取图片所需要的请求头
picHead = {
':authority': 'img9.doubanio.com',
':method': 'GET',
':path': '/view/photo/l/public/p2309770674.webp',
':scheme': 'https',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
'cache-control': 'max-age=0',
'if-modified-since': 'Wed, 21 Jan 2004 19:51:30 GMT',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
# 下载图片
res = requests.get(url,headers = picHead);
# 打开文件
f = io.BytesIO(res.content);
# 打开图片
im = Image.open(f)
# 加载图片
im.load();
# 存储图片
im.save('./temp.jpg');
#休眠一段时间防止频率过高爆炸
time.sleep(1)
运行之后报了错:
我猜想可能是冒号的原因,然后把冒号去除之后再爬,倒是不会报不识别的错了,但是获得的流是空的,于是我百度找到了原因,这个东西叫做HTTP2:
HTTP2即未来
看起来很牛逼不过对我的问题没有什么帮助,其他提到这个问题的也没有解决方案,这时我突然想到,如果我用火狐浏览器试试重新发送一下请求呢,于是我复制这个url在火狐浏览器中打开,看到了如下的情况:
可以看到火狐浏览器中并没有那个讨厌的冒号,复制他的请求头再到代码中重新爬取,可以看到下载成功。
这个解决方法有点不太好,因为并没有从本质上解决这个问题,猜测可能是火狐并没有用HTTP2的方式来读取请求,但是有时候解决方案就是能用就行,如果有代码层面的解决方法也请分享一下吧。