喜欢必应的每日图片,但是通过官方的下载渠道下载却有水印,看起来未免有点不舒服。因此不妨写一个小小的爬虫用于下载非水印的图片,并让它每天按时启动下载图片。
抓包
首先打开必应的网址https://cn.bing.com/
,一张高清的大图呈现在眼前。熟练的按下F12
并切换到network
选项卡,由于我们要抓的是图片,所以点一下Img
过滤一下。刷新,可以看到第一个就是我们要找的无水印的图片:
看一下请求头,看来需要id
,rf
,和pid
这三个参数,rf
看起来怪怪的,所以直接Ctrl+Shift+F
搜一下rf
,一不小心就看到了最下面的index
下面包含了要找的三个参数:
真是喜闻乐见,看来地址就隐藏在网页源代码里面。那样就很好办了。Ctrl+U
查看一下网页源代码,再搜rf
,找到在标签的那一行,这样可以方便使用代码定位。
<div id="bgImgProgLoad" data-ultra-definition-src="/th?id=OHR.MaldivesDragonfly_EN-CN4875511803_UHD.jpg&rf=LaDigue_UHD.jpg&pid=hp&w=1920&h=1080&rs=1&c=4" data-explicit-bing-load="false" data-dynamic-size="true">
接下来,回到抓包的页面,选中图片的请求,并点击右键 -> copy -> copy as cUrl(bash):
然后到Convert cURL command syntax to Python requests..这个网站,在curl command
下面的输入框里面粘贴刚才复制的文本,在下面的Language处选择Python,接下来把旁边的Python reuqests
代码复制到Pychram
或这其它编辑器中,像下面这样:
import requests
headers = {
'pragma': 'no-cache',
'cookie': 'MUID=34F275FB5B7264163D0879485F7267B0; SRCHD=AF=NOFORM; SRCHUID=V=2&GUID=EF39597735204CE99624CF596CA4774B&dmnchg=1; _EDGE_CD=u=en-us; MSCC=1; _TTSS_OUT=hist=["en"]; _tarLang=default=zh-CHS; ENSEARCH=BENVER=1; SRCHUSR=DOB=20190505&T=1569814470000; SerpPWA=reg=1; _EDGE_S=SID=0E7BDA7155D6641513BED78754F86598; MUIDB=34F275FB5B7264163D0879485F7267B0; ipv6=hit=1571130748800&t=4; ULC=P=18C8F|7:3&H=18C8F|9:4&T=18C8F|9:4:3; _SS=SID=0E7BDA7155D6641513BED78754F86598&HV=1571127174&bIm=584; SNRHOP=I=&TS=; SRCHHPGUSR=CW=2543&CH=421&DPR=1&UTC=480&WTS=63706723947',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
'sec-fetch-mode': 'no-cors',
'accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
'cache-control': 'no-cache',
'authority': 'cn.bing.com',
'referer': 'https://cn.bing.com/',
'sec-fetch-site': 'same-origin',
}
params = (
('id', 'OHR.MaldivesDragonfly_EN-CN4875511803_1920x1080.jpg'),
('rf', 'LaDigue_1920x1080.jpg'),
('pid', 'hp'),
)
response = requests.get('https://cn.bing.com/th', headers=headers, params=params)
#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.get('https://cn.bing.com/th?id=OHR.MaldivesDragonfly_EN-CN4875511803_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp', headers=headers)
加一行存储代码看能不能正常存储:
...
with open('test.jpg', 'wb') as f:
f.write(response.content)
可以看到项目中多了一张名为test.jpg
的图片,打开看下确定无误。接下来正式开始编写采集代码。
编写爬虫代码
根据上面的浏览器代理写一下请求https://cn.bing.com/
的代码,这次请求头就不用搞那么多参数了:
import requests
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
}
response = requests.get('https://cn.bing.com/', headers=headers)
图片当然需要一个正经的标题,在首页右下角可以看到一个小圈圈,里面的文字像一个倒着的感叹号(其实是 i 吧..),鼠标放在上面会显示一串中文字符,看起来就像图片的标题一样:
点右键检查元素,可以看到具体的信息:
复制class="sc_light"
到网页源代码里搜一下,可以找到就放心了,下面开始定位这两个元素,既然要定位的元素不多,而且足够简单,就不用再解析整个网页了,直接使用正则比配一下即可,注意匹配到的地址是不完整的,使用urljoin
拼接一下:
import re
from urllib.parse import urljoin
img_url = re.search(r'<div id="bgImgProgLoad" data-ultra-definition-src="(.*?)"', response.text).group(1)
img_url = urljoin(response.url, img_url)
title = re.search(r'class="sc_light" title="(.*?)"', response.text).group(1)
print(img_url, title)
# 输出
# https://cn.bing.com/th?id=OHR.MaldivesDragonfly_ZH-CN5949519396_UHD.jpg&rf=LaDigue_UHD.jpg&pid=hp&w=1920&h=1080&rs=1&c=4 蜻蜓翅膀特写 (© Azwar Thaufeeq/500px/Getty Images)
输出很符合期望,接下来写一下保存图片的方法。由于标题中可能含有/
字符,会与系统路径产生冲突,所以要先将/
替换为空格,另外请求头页不需要再重新定义了,在上面的起初上加一个referer
即可(其实不加也没什么关系):
headers['referer'] = response.url
r2 = requests.get(img_url, headers=headers)
title = title.replace('/', ' ')
with open(f'images/{title}.jpg', 'wb') as f:
f.write(r2.content)
注意图片的路径,为了避免代码文件与图片文件在一起让人感觉混乱,所以单独为图片新建一个iamges
文件夹,放在代码的同级目录下。
最后封装下所有代码保存为bingimg.py
:
# bingimg.py
import re
import requests
from urllib.parse import urljoin
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'
}
def download_bing_daily_image():
r = requests.get('https://cn.bing.com/', headers=headers)
try:
url = re.search(r'<div id="bgImgProgLoad" data-ultra-definition-src="(.*?)"', r.text).group(1)
title = re.search(r'class="sc_light" title="(.*?)"', r.text).group(1)
except AttributeError:
print('Wrong parse rules.')
return
image_url = urljoin(r.url, url)
title = title.replace('/', ' ')
headers['referer'] = r.url
r = requests.get(image_url, headers=headers)
with open(f'images/{title}.jpg', 'wb') as f:
f.write(r.content)
if __name__ == '__main__':
download_bing_daily_image()
配置定时抓取
Windows上的任务计划程序可以很好的定时执行写好的程序。在左下角的搜素框输入任务计划程序
,打开。
点击右边的"创建任务":
在弹出的对话框中,首先输入一个名字,随意输即可,我这里输的是bingdailypic
。
切换到"触发器"选项卡,点击新建,选中每天,然后设置一下每天的具体时间即可,点击确定。
再切换到操作选项卡,点击新建,程序或脚本处点击浏览找到Python安装位置,选择python.exe
文选。我这里是C:\Users\Administrator\AppData\Local\Programs\Python\Python37\python.exe
,参数位置写上爬虫脚本所在位置,我这里是E:\bing\bingimg.py
。
后面的条件和设置就按需设置即可了。配置好后,只要指定时间段内电脑没有关机,图片就会正常下载了。
网友评论