必应默认加载1080P图片作为背景,然而背景的最大分辨率远不止1080P。经过60天的爬虫抓取,获取的图片中最大的超过8K,平均维持在4K水平。

API与打包文件

请勿滥用,不过欢迎有能力的人撰写完整API。

如果你想获取2020年2月6日至当天之间的高清壁纸,可以使用我提供的简易API:https://bing.raincorn.top/imgs/ 然后加上你需要获取图片的那一天日期(以.jpg结尾),例如https://bing.raincorn.top/imgs/20200406.jpg可以获取到4月6日的图片。如果你想获得60天的打包文件,可以访问https://t.cn/A6Zdy6Ap

爬虫源代码

简而言之,通过更改图片URL即可获取到UHD+图片。
如果你想知道更多,请继续阅读,源文件全部公开在https://github.com/Dove-real/Pytbt

引入库与Header处理

1
2
3
4
5
6
7
8
9
10
import requests
import re
import time
from PIL import Image
import os
# 使用本机UA
header = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"}
html = requests.get('https://cn.bing.com/',
headers=header).text

其中requests用于请求,re用于正则处理,time用于获取到时间戳便于命名,PIL用于获取图片尺寸,os则用于文件保存。

获取正常图片URL

访问https://cn.bing.com/,然后打开开发者工具,进入NetWork后刷新获取到背景刷新时候的URL,对照网页源代码写出正则表达式。

正则表达式如下:

1
2
img_id = re.findall(r'.*?background-image:url\((.*?)&.*?', html)
img_fhd = img_id[0]

修改img_fhd

这其实是我瞎撞出来的

第二步获取到的URL简化后得到https://cn.bing.com/th?id=OHR.CastleDay_ZH-CN8752542375_1920x1080.jpg,然后将1920x1080更换为UHD即可,如下:

1
2
3
img_uhd = img_fhd.replace('1920x1080', 'UHD')
img_url = "https://cn.bing.com"+img_uhd
print(img_url)

命名与保存

图片将会保存到工作目录的根目录下,注意,工作目录指的是当前用户的根目录。Windows下指C:\Users\Raincorn,Linux下面指/root,其中Raincorn与root为我的用户名,当为普通用户时Linux下根目录指/home/raincorn

1
2
3
4
5
6
7
8
9
10
11
# 以年月日命名图片,并储存到本地。
name = time.strftime('%Y%m%d')+'.jpg'
img = requests.get(img_url)
with open(name, 'wb') as f:
f.write(img.content)
f.close()
print('Save as', name)

# 获取图片尺寸
path = os.path.join(os.getcwd(), name)
img_file = Image.open(path)

异常处理

脚本运行时间小于30S,一般情况下不需要做异常处理。然而在2020年3月23日时,必应背景发生了变化,背景使用了图片+视频,故添加此段。

1
2
3
4
5
6
7
8
9
# 异常情况处理,即当天图片不符合要求,一般出现在当天背景为MP4的情况下
if(img_file.width < 250):
img_url = "https://cn.bing.com"+img_fhd
img = requests.get(img_url)
with open(name, 'wb') as f:
f.write(img.content)
f.close()
print('Save as', name)
img_file = Image.open(path)

微信推送

为加快爬取失败时人工干预的速度,加上此段,可在每次爬取成功时向微信推送图片详情。

1
2
3
4
5
6
7
8
9
# 通过ServerChan发送通知到微信
data = {
'text': 'Bing首页图片已抓取',
'desp': name+str(img_file.size)
}
requests.post(
'https://sc.ftqq.com/{Key}.send', data=data
)
# 注意{key}需要更改为你自己的Key。

完整源文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 用于爬取Bing首页背景,获得UHD+分辨率的图片。
import requests
import re
import time
from PIL import Image
import os
# 使用本机UA
header = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"}
html = requests.get('https://cn.bing.com/',
headers=header).text

# 正则表达式寻找图片URL并尝试将之更改为高分辨率图片地址
img_id = re.findall(r'.*?background-image:url\((.*?)&.*?', html)
img_fhd = img_id[0]
img_uhd = img_fhd.replace('1920x1080', 'UHD')
img_url = "https://cn.bing.com"+img_uhd
print(img_url)

# 以年月日命名图片,并储存到本地。
name = time.strftime('%Y%m%d')+'.jpg'
img = requests.get(img_url)
with open(name, 'wb') as f:
f.write(img.content)
f.close()
print('Save as', name)

# 获取图片尺寸
path = os.path.join(os.getcwd(), name)
img_file = Image.open(path)

# 异常情况处理,即当天图片不符合要求,一般出现在当天背景为MP4的情况下
if(img_file.width < 250):
img_url = "https://cn.bing.com"+img_fhd
img = requests.get(img_url)
with open(name, 'wb') as f:
f.write(img.content)
f.close()
print('Save as', name)
img_file = Image.open(path)

# 通过ServerChan发送通知到微信
data = {
'text': 'Bing首页图片已抓取',
'desp': name+str(img_file.size)
}
requests.post(
'https://sc.ftqq.com/{Key}.send', data=data
)