Python 通过Bing壁纸接口获得UHD分辨率的壁纸
前言
买了新的2K显示器之后,1080p的壁纸已经无法满足了,2K显示器看壁纸都糊了:(,但还是喜欢每日一更新的bing壁纸。这个时候怎么办呢?我看网上每个玩家做bing壁纸同步都是有超高清的壁纸可以下载的,不过都需要登录才能下载超高清壁纸,不登录的就只能下载1080p分辨率的,难受!既然他们的超高清壁纸也是通过bing壁纸接口获得的,那或许我也能通过接口下载:D。
经过分析,我发现只需要将获得的壁纸url中的“1920x1080”改为“UHD”,就可以获得超高清的壁纸了,不过分辨率并不是固定的4K,也可能是8K的,如下查看bing的html源码。
接下来就是代码时间了!
Python获取链接并下载
分析json
通过bing壁纸接口获得的json如下,由于数据比较多,做了以下简略,images节点下的每一个子元素的url就是图片的链接,不过是1080p的,而且url最前面没有加上bing的域名
1 { 2 "images": [ 3 { 4 "startdate": "20201003", 5 "fullstartdate": "202010031600", 6 "enddate": "20201004", 7 "url": "/th?id=OHR.MontageJupiterIo_ZH-CN2512372897_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp", 8 "urlbase": "/th?id=OHR.MontageJupiterIo_ZH-CN2512372897", 9 "copyright": "木星及木卫一的蒙太奇图像 (© NASA/Johns Hopkins University Applied Physics Laboratory/Southwest Research Institute/Goddard Space Flight Center)", 10 "copyrightlink": "/search?q=%e6%9c%a8%e6%98%9f&form=hpcapt&mkt=zh-cn", 11 "title": "", 12 "quiz": "/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20201003_MontageJupiterIo%22&FORM=HPQUIZ", 13 "wp": true, 14 "hsh": "03b3a0c34dbb46fb90f4e3cdd2890ced", 15 "drk": 1, 16 "top": 1, 17 "bot": 1, 18 "hs": [] 19 }, 20 ... ... 21 ], 22 "tooltips": { 23 "loading": "正在加载...", 24 "previous": "上一个图像", 25 "next": "下一个图像", 26 "walle": "此图片不能下载用作壁纸。", 27 "walls": "下载今日美图。仅限用作桌面壁纸。" 28 } 29 }
下载图片
下面的代码示例使用到了requests
和jsonpath
这两个框架,如果还没有安装的,先使用pip安装
pip install requests jsonpath
接下来是python代码
1 import requests 2 from jsonpath import jsonpath 3 from time import time 4 from json import load 5 from os.path import exists 6 7 # 模拟浏览器User-Agent 8 headers = { 9 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.70' 10 } 11 12 13 def get_wallpaper_urls(): 14 """获取图片链接""" 15 # 随机时间戳 16 timestamp = time() 17 r = requests.get( 18 url=f"https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=8&nc={int(timestamp * 1000)}&pid=hp", 19 headers=headers 20 ) 21 # print(r.json()) 22 # 保存图片json 23 with open('bing-wallpaper.json', 'wb') as f: 24 f.write(r.content) 25 26 print('done') 27 28 29 def collect(s=''): 30 """处理图片链接,将1080p替换为UHD的超高清格式,并且拼接上bing的域名""" 31 return 'https://cn.bing.com' + s.replace('1920x1080', 'UHD') 32 33 34 def parse_json(file_path=None): 35 """解析图片链接并下载""" 36 if file_path and exists(file_path): 37 wallpapers = {} 38 # 打开下载好的json文件 39 with open(file_path, 'rb') as f: 40 wallpapers = load(f) 41 # 解析提取所有的图片链接 42 urls = jsonpath(wallpapers, '$.images[*].url') 43 if isinstance(urls, list): 44 # 处理图片 45 urls = map(collect, urls) 46 # 下载图片 47 for i in urls: 48 download_images(i) 49 50 51 def download_images(image_url): 52 """下载图片""" 53 r = requests.get(url=image_url, headers=headers) 54 # 做下判断,忽略无法下载的图片,或者说是无效的图片链接 55 if r.status_code == 200 and 'image' in r.headers['content-type']: 56 print(f'download images for {image_url}') 57 # 这里是根据图片链接的特征提取图片文件名,其实也可以直接用时间戳来命名文件,更快一些 58 image_url = image_url[30:].split('&')[0] 59 # 下载好的图片保存到当前py文件同级的imgs目录下 60 with open('imgs/' + image_url, 'wb') as f: 61 f.write(r.content) 62 63 64 if __name__ == '__main__': 65 get_wallpaper_urls() 66 parse_json('bing-wallpaper.json')
下载结果
下载好的壁纸确实是超高清格式的,有4K的也有8K的