这个博客系统的背景使用的是bing的背景图片。当时是写死的,总觉得不美观。于是乎就想更改为每日自动替换。
思路:每日定时从网页中分析背景图片的地址,然后将背景图片地址保存至数据库,页面渲染的时候将该参数透传到前台。
本文:仅罗列背景图片分析部分。
from bs4 import BeautifulSoup
import requests
from urllib import parse
ua = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
def download_image(image_url):
'''
如果想下载图片,可以使用该方法。个人不喜欢下载图片,一是需要维护文件,二是不占用自有服务器带宽。
解析请求地址 https://s.cn.bing.net/th?id=OHR.Waterleidingduinen_ZH-CN1430683267_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&qlt=50
将参数 rf的值作为文件的名称
:param image_url: 背景图片的地址
:return:
'''
print(image_url)
image_parse = parse.urlparse(image_url)
filename = parse.parse_qs(image_parse.query)['rf'][0]
resp = requests.get(image_url, headers={
"User-Agent": ua
})
with open(filename, 'wb') as file:
file.write(resp.content)
def extract_image_from_page():
'''
从页面中直接获取背景图片地址。
'''
res = requests.get("https://cn.bing.com/chrome/newtab", headers={
"User-Agent": ua
})
soup = BeautifulSoup(res.text, features="html.parser")
tag = soup.find("link", id="preloadBg")
return tag['href']
if __name__ == '__main__':
download_image(extract_image_from_page())
其实这个没有什么可以分享的,也属于非常基本操作。下面说点不一样的知识点,url地址有六部分组成 <scheme>://<netloc>/<path>;<params>?<query>#<fragment>
我们在解析的时候,一般的方式是使用字符串查询加截取的方式。这种方式对于大部分请求是没有问题的。如果经常分析协议就一定遇到过这种类型。
https://s.cn.bing.net/th?id=OHR&test=abc%20edc¶m=1¶m=3
这个时候你会发现test参数与param参数的特殊性。如果遗漏的话,程序就会存在潜在的bug. 最好的方式是使用urllib.parse_qs进行解析。即代码的17行。其中该方法对应的源码如下:
pairs = [s1 for s1 in qs.split(separator)]
r = []
for name_value in pairs:
if not name_value and not strict_parsing:
continue
nv = name_value.split('=', 1)
if len(nv) != 2:
if strict_parsing:
raise ValueError("bad query field: %r" % (name_value,))
# Handle case of a control-name with no equal sign
if keep_blank_values:
nv.append('')
else:
continue
if len(nv[1]) or keep_blank_values:
name = nv[0].replace('+', ' ')
# 这里会处理转义
name = unquote(name, encoding=encoding, errors=errors)
name = _coerce_result(name)
value = nv[1].replace('+', ' ')
value = unquote(value, encoding=encoding, errors=errors)
value = _coerce_result(value)
r.append((name, value))
return r
从源码中可以看出,高手写的代码是非常的稳健。关于url的相关知识,后续会专门写一篇博客详细介绍。
对于定时请求,最好的方式是直接使用服务器的crontab.crontab格式不清晰的话,可以参考下文的链接。
[========]
其实Bing图片搜索API提供了每日精选图片接口,URL为:https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN
import requests
response = requests.get("https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN")
result = response.json()
imageUrl = ("https://www.bing.com" + result["images"][0]["url"])
print(imageUrl)
print(result)
其他语言自行进行解析即可。
参考链接: