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

本篇能达到目的,但踩坑较多,可以直接看更新后的文章

情境

感觉桌面壁纸太单调, 没有合适的壁纸来源, 手动更新太麻烦…不难发现, 每天必应的首页图片都会更新, 而且图片可以直接拿来作壁纸. 所以, 动动手就可以解决上面的问题

思路

  • 获取必应首页图片 (python requests 库 )
  • 保存为本地文件
  • 文件自动命名: 依据当天日期即可 (python time 库)
  • 通过命令将图片设置为壁纸 (ubuntu环境, gnome桌面, python os 库)
  • 让代码每天跑一遍 (crontab命令)

代码实现

#!/usr/bin/python3
# -*- "encoding: utf-8" -*-

import requests
import time
import os

#图片为必应首页图片, 此链接来源于知乎搜索
img_url = "https://area.sinaapp.com/bingImg/"
#根据日期自动确定文件名
date = time.localtime()
year = date.tm_year
month = date.tm_mon
day = date.tm_mday
filename = "bing_%s_%s_%s.jpg" % (year, month, day)

#获取图片并保存在本地
r = requests.get(img_url)
with open("/home/ubuntu/Wallpapers/%s"%filename, "wb") as f:
    f.write(r.content)

#执行shell命令更换壁纸
os.system("gsettings set org.gnome.desktop.background picture-uri 'file:///home/ubuntu/Wallpapers/%s'" % filename)

接下来测试一下代码能否正确执行

在命令行直接执行这段代码没有问题, 图片能够正常下载并保存. 壁纸被正常更换

ubuntu@ubuntu-X550VQ:~$ ./autoUpdateWallpapers.py

但是, 不能每天都自己执行一遍这个程序吧, 所以借助 cronanacron 让代码每天跑一遍就行了

然而到最后才发现, crongsetting 并不友好
—>所以如果不愿试错不想折腾, 请跳过下面将程序放入 cron.daily 目录的方法<—

具体动作:

  • 给脚本赋予执行权限
chmod 755 autoUpdateWallpapers.py
  • 把脚本放到 /etc/cron.daily 目录下
sudo mv ./autoUpdateWallpapers.py /etc/cron.daily/autoUpdateWallpapers

sudo chown root /etc/cron.daily/autoUpdateWallpapers
sudo chgrp root /etc/cron.daily/autoUpdateWallpapers

脚本放到cron.daily下没有被执行…检查了下面的几个问题:

  1. 放到 cron.*/ 目录下的文件由 run-parts 执行, 所以文件名有一定要求, 如不能带 点(dots) 等, 所以将脚本移动到目标文件夹之后就不要写后缀了;

(检查文件是否符合规范使用命令 run-parts --test /etc/cron.daily/ 在命令输出列表中的才是符合要求的) 详细查看 run-parts 文档

  1. 这个目录下的所有可执行文件的所有者都必须是root, 所以要将脚本的拥有者(owner)改为root

    这是节选的cron 官方文档说明:

    As described above, the files under these directories have to be pass some sanity checks including the following: be executable, be owned by root, not be writable by group or other and, if
    symlinks, point to files owned by root. Additionally, the file names must conform to the filename requirements of run-parts: they must be entirely made up of letters, digits and can only con‐
    tain the special signs underscores (’_’) and hyphens (’-’). Any file that does not conform to these requirements will not be executed by run-parts. For example, any file containing dots will
    be ignored. This is done to prevent cron from running any of the files that are left by the Debian package management system when handling files in /etc/cron.d/ as configuration files (i.e.
    files ending in .dpkg-dist, .dpkg-orig, and .dpkg-new).

  2. 放入 cron.daily/ 文件夹中的文件系统会保证每天执行一次, 具体时间由 crontabanacron 配置情况决定. 配置文件分别为 /etc/crontab/etc/anacrontab .

还是不能成功更换壁纸…那就不借助 cron.daily/ 了, 直接用crontab设置循环任务

  • 将脚本从 cron.daily/ 文件夹移出至其他文件夹, 比如 /usr/bin/ 目录下
  • $HOME 下新建一个shell脚本 autoUpdateWallpapers , 通过shell脚本来调用python程序
#!/bin/sh
python3 /usr/bin/autoUpdateWallpapers.py
  • 使用 crontab -e 将shell脚本写入当前用户的定时任务列表中, 此时时间是明确确定的. 缺点是一旦到了执行时间而此时计算机没有正常工作, 那么此次任务就会被跳过. 相反, 放在 cron.*/ 系列文件夹下的脚本会由 anacron 进行时间间隔的确认, 能进行 “弥补” .
#命令行输入 crontab -e 回车, 在打开的文件中加入下面这行
0 22 * * * /home/ubuntu/autoUpdateWallpapers

再次测试, 图片能正常下载, 但是壁纸还是没有更换

  • 最终在 一个网站的评论 找到了问题所在:

gsettings won’t work from cron, however. you need to set the DBUS_SESSION_BUS_ADDRESS environment >variable in order for gsettings to work. You can do that by adding these two lines before gsettings
PID=$(pgrep gnome-session)
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-)
– willbradley Jan 13 at 0:25

  • 按照上面所说, 在shell脚本中增加了两条shell命令 (具体含义不是很懂)
#!/bin/sh

PID=$(pgrep gnome-session)
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-)

python3 /usr/bin/autoUpdateWallpapers.py
  • 然后壁纸终于能正常每天自动更换了

你可能感兴趣的:(Python)