Python实用: 桌面壁纸每日自动更新为必应首页背景图

此为已有的一篇博文的更新
环境依旧为:Ubuntu 16.04
更新点:直接从Bing首页爬取图片,不再从已有的第三方链接直接下载。

(写上一篇博文的时候踩了不少坑,图片也不是直接从Bing首页爬取,而是来自第三方已有的链接。 写这篇文章的时候已经有了上一次的基础,以及爬取教务课表的尝试,所以过程很顺利。)

前期准备

  • 指定由python3执行
#!/usr/bin/python3
  • 指定编码为utf-8
# -*- coding: utf-8 -*-
  • 引入必要的库
import requests  #发起网页请求
import re  #使用正则表达式来匹配到图片网址
import time  #获取当前时间,用来文件命名
import os  #执行shell命令
  • 可以先构建好文件名
time = time.localtime()  #获取当前时间
filename = 'bing_%s_%s_%s.jpg' % (time.tm_year, time.tm_mon, time.tm_mday)  #用时间构建好文件名

实现:

  • 爬取Bing首页
url = 'https://cn.bing.com'  #国内Bing网址
headers = {'user-agent': 'Mozilla/5.0'}  #伪装成浏览器,降低访问失败的概率

r = requests.get(url, headers=headers)  #get到网页
  • 从网页源码中解析出首页背景图片的url
imgurl = url + '/' + re.search(r'url: ".*.jpg"', r.text).group()[6:-1]

解释两下:
re.search(r'url: ".*.jpg"', r.text)
r.text 是网页的源码(r只是requests中get请求返回来的一个对象,该对象的text属性才是源码)
r'url: ".*.jpg"' 是正则表达式,将会匹配到 以 url: " 开头,以 .jpg" 结尾,中间是若干个任意字符 的字符串
re.search 方法如果匹配到结果,将会返回一个含有目标字符串的对象,通过 group() 方法得到匹配到的字符串
我只需要字符串中的url部分,所以对字符串做一个切片操作,取第 6 到第 -2 个字符
此时截取的url是不完整的,所以要在前面加入 url 变量里面存储的Bing首页的网址进行补全。

  • 图片网址拿到了,那接下来就是访问然后保存到文件了
img = requests.get(imgurl)  #get到图片所在的网页内容
with open('/home/ubuntu/Wallpapers/%s'%filename, 'wb') as fp:
        fp.write(img.content)

with ... as ... 是推荐的打开文件的格式
wb 以二进制+写形式打开文件,文件不存在会自动新建
fp 是文件的句柄
fp.write 是以二进制写入
img.content 是网页内容的二进制形式,图片、音频的文件流都是要用二进制形式的

  • 执行shell命令更换壁纸
 #在执行反斜杠后的更换壁纸的命令之前,要先执行反斜杠前的那两条shell命令,不然壁纸换不成。这我在上篇博文提到过。
os.system("PID=$(pgrep gnome-session);export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-);\
gsettings set org.gnome.desktop.background picture-uri 'file:///home/ubuntu/Wallpapers/%s' &>> /home/ubuntu/autoUpateWallpapers.log" % filename)

其中,所有输出都会重定向到 autoUpdateWallpapers.log

os.system("echo '%s.%s.%s %s:%s:%s更换了一次壁纸' >> /home/ubuntu/autoUpateWallpapers.log" % (time.tm_year, time.tm_mon, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec))

执行完代码,写一条记录进到log文件中

  • 最后,可以加个if…else把爬取首页的包裹一下
if r.status_code == 200:   #status_code是状态码,不为200说明爬取没有正常获取到Bing首页
    imgurl = url + '/' + re.search(r'url: ".*.jpg"', r.text).group()[6:-1]
    img = requests.get(imgurl)
    with open('/home/ubuntu/Wallpapers/%s'%filename, 'wb') as fp:
        fp.write(img.content)
    #在执行反斜杠后的更换壁纸的命令之前,要先执行反斜杠前的那两条shell命令,不然壁纸换不成。这我在上篇博文提到过。
    os.system("PID=$(pgrep gnome-session);export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-);\
gsettings set org.gnome.desktop.background picture-uri 'file:///home/ubuntu/Wallpapers/%s' &>> /home/ubuntu/autoUpateWallpapers.log" % filename)
    os.system("echo '%s.%s.%s %s:%s:%s更换了一次壁纸' >> /home/ubuntu/autoUpateWallpapers.log" % (time.tm_year, time.tm_mon, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec))

else:  #没正常获取到Bing首页,那其他操作自然不要做了,输出一段信息就好了。当然这段信息也是会被重定向到log文件的,这会在设置定时任务的时候设置
    print('OpenURLError.')
  • 最最后,给文件赋予执行权限,加入到当前用户的定时任务里
chmod 755 ./autoUpdateWallpapers.py

给程序赋予执行权限后就不需要敲python3加文件名来执行程序了

mv ./autoUpdateWallpapers.py ~/bin/autoUpdateWallpapers

这里相当于两步操作:去掉后缀(重命名文件),这样看着舒服些
把程序移动到 home 目录下的 bin 文件夹内。没有这个文件夹?那就建一个。
--------------------------------------------------------插几句闲话---------------------------------------------------------------
建这个目录并把自己写的程序放到这个目录里是很方便的。因为系统已经预留了这个目录的位置,并且默认把它放到了环境变量里面,即使你还没有建这个文件夹。

打开 ~/.profile 文件看看即可满足好奇心。
该文件末尾会有下面两行

set PATH so it includes user's private bin directories                    
PATH="$HOME/bin:$HOME/.local/bin:$PATH"

$HOME/bin 目录赫然在列
--------------------------------------------------------下面回到正题--------------------------------------------------------------

crontab -e  #在当前用户身份下执行这个命令

这将打开当前用户的定时任务配置文件
在文件末尾加入下面这行

#每日自动更换壁纸
0  23  *   *   *   /home/ubuntu/bin/autoUpdateWallpapers &>> /home/ubuntu/autoUpateWallpapers.log

0 过零分钟(整点)
23 晚上十一点
* * * 依次代表 日 月 星期,详细请 查找 crontab 相关内容
接下来跟的就是命令了,&>> 所有输出重定向到log文件
(加注释是个好习惯,这样每个定时任务一看就知道是用来干嘛的)

完成

学习中,如有错误,欢迎留言评论指出

你可能感兴趣的:(Python)