我有一篇文章定时自动获取Bing每日壁纸并保存备用中使用的API挂了,用的是别人提供的接口。为了解决这个问题,我决定重新写个脚本帮我下载壁纸,这次用Python以及官方提供的接口。

本文记录一下如何使用这个接口,备忘。

这是官方提供的接口:

https://cn.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=zh-CN

补充一下接口的参数:

参数名称值含义
format(非必须)返回数据格式,默认返回xml格式
js(返回json格式)
xml(返回xml格式)
idx(非必须)请求图片截止天数
0 今天
-1 截止中明天(预准备的)
1 截止昨天,类推(最大值7,也即是最多获取到7天前的图片)
n(必须)1-8 返回请求数量,最多一次获取8张图片
mkt(非必须)地区
zh-CN
...

我们尝试用上面的url发送请求,可以看到返回值如下:

图中标识的位置就是我们得到的壁纸的地址了,只需要使用域名+获取到的地址就可以下载壁纸了:

https://cn.bing.com/th?id=OHR.VancouverFall_ZH-CN9824386829_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp

但是这个地址默认是返回1920x1080分辨率的壁纸,而我想下载自己需要的其他分辨路的壁纸,怎么办呢?

其实不难发现,url下一行还有一个字段urlbaseurl其实是在urlbase基础上添加了分辨率和拓展名后缀,所以我们只要改变这个后缀就可以下载我们需要的分辨率的壁纸了。

接下来就是用Python去实现啦,还是Python最简单啊,几行代码搞定数据的获取:

import requests

bing_url = "http://www.bing.com/HPImageArchive.aspx"
data = {
    "ids": 0,
    "n": 1,
    "format": "js"
}
r = requests.get(bing_url, params=data)
print(r.json())

获取到的jason信息如下:

{
    'images': [{
        'startdate': '20190921',
        'fullstartdate': '201909211600',
        'enddate': '20190922',
        'url': '/th?id=OHR.VancouverFall_ZH-CN9824386829_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp',
        'urlbase': '/th?id=OHR.VancouverFall_ZH-CN9824386829',
        'copyright': '鸟瞰生长在森林中的树木,加拿大不列颠哥伦比亚省温哥华 (© Michael Wu/EyeEm/Getty Images)',
        'copyrightlink': 'https://www.bing.com/search?q=%E6%A3%AE%E6%9E%97%E4%B8%AD%E7%9A%84%E6%A0%91%E6%9C%A8&form=hpcapt&mkt=zh-cn',
        'title': '',
        'quiz': '/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20190921_VancouverFall%22&FORM=HPQUIZ',
        'wp': True,
        'hsh': 'f56f92d088e72d92e1abceb2005ff38b',
        'drk': 1,
        'top': 1,
        'bot': 1,
        'hs': []
    }],
    'tooltips': {
        'loading': '正在加载...',
        'previous': '上一个图像',
        'next': '下一个图像',
        'walle': '此图片不能下载用作壁纸。',
        'walls': '下载今日美图。仅限用作桌面壁纸。'
    }
}

很乱是不是,接下来继续提取我们需要的信息,我们需要日期和分辨率用作保存文件的文件名,URL用于下载文件:

image = r.json()["images"][0]
base_url = image["urlbase"] # 
image_date = image["enddate"]

万事具备,只欠东风。我在网上找到了所有可用的分辨率,每个分辨率都生成对应的文件夹,用来保存同一尺寸的壁纸,代码如下:

# 已知可用分辨率
ratios_knowned = {"1920x1200",
                  "1920x1080",
                  "1366x768",
                  "1280x768",
                  "1024x768",
                  "800x600",
                  "800x480",
                  "768x1280",
                  "720x1280",
                  "640x480",
                  "480x800",
                  "400x240",
                  "320x240",
                  "240x320"}
# 脚本文件所在路径
script_dir = os.path.dirname(sys.argv[0])

for ratio in ratios_knowned:
    # 为每个分辨率创建文件夹
    ratio_path = script_dir + "/" + ratio
    if os.path.exists(ratio_path) is False:
        os.makedirs(ratio_path)
    # 分辨率后缀
    suffix = "_" + ratio + ".jpg"
    file_name = "bing_" + image_date + suffix
    file_path = ratio_path + "/" + file_name
    down_url = "https://bing.com" + base_url + suffix
    r_img = requests.get(down_url).content
    with open(file_path, "wb") as f:
        print("Saving: ", file_path)
        f.write(r_img)

保存的文件在脚本所在目录下,这个样子的:

现在可以把脚本放到服务器上,然后设置定时任务,每天获取壁纸了。参考定时自动获取Bing每日壁纸并保存备用

搜索资料的时候,我发现了一个好用的API,分享一下,我的可用分辨率也是从这里获得的。

https://github.com/xCss/bing/tree/v1.0.0