PyAutoGUI 是 GUI 功能强大自动化方案,但 UI 程序的运行环境选择与配置也是一大难题。
系统选择
为了让环境可迁移,免维护,资源消耗少,必须使用虚拟化的方案。
虽然 PyAutoGUI 支持 Windows/macOS/Linux 三个平台。但是各有各的弊端。
- Windows 的系统臃肿且开发环境不友好
- macOS 的权限管理过于严格且虚拟化难度大,高dpi的屏幕也不适合自动化
- Linux 就是最好的选择了,但执行的应用可能不支持 Linux,必须引入 Wine
综合以上情况考虑,系统环境选择如下
- pve: 宿主机系统,也可以选择别的环境
- debian: 客户机系统,目前是 debian 12, 方便使用 deepin 的 wine 程序
- mate: 桌面环境,比较轻量,实测兼容性比 xfce 好
- 星火应用商店: 方便安装各种国内软件和 Wine 程序
- 统信 Windows 应用兼容引擎: 在星火应用商店中安装,可以用于安装和打包商店中没有的程序
虚拟机配置
步骤
- 创建好 pve 虚拟机, 安装 debian,选择 mate 桌面
- 设置分辨率:控制中心 -> 显示器 -> 设置为 1920x1080
- 关闭自动睡眠:控制中心 -> 电源管理 -> 动作和显示修改为
从不
- 关闭屏幕保护:控制中心 -> 屏幕保护程序 -> 取消勾选所有选项
- 安装
gnome-screenshot
: 用于 PyAutoGUI 内部调用截图 - 安装星火应用商店(可选)
- 安装统信 Windows 应用兼容引擎(可选):在星火应用商店中安装
- 火焰截图(可选):在星火应用商店中安装,更方便对应用的按钮和文字截图。
其他说明:
- 如果不关闭自动睡眠和屏幕保护,PyAutoGUI 就无法截取到应用的图像,也就无法操作了。
- 图形显示协议默认选 x11,wayland 对显卡有要求,虚拟机不方便处理。
PyAutoGUI 使用技巧
远程登录调试
pve 默认图片控制台不太方便,不能复制粘贴,所以使用远程登录调试
由于系统使用 x11 环境,这里使用 xrdp 作为远程服务端。
如果以后更新到 wayland,可以使用 gnome-remote-desktop
。1
2sudo apt update
sudo apt install xorgxrdp xrdp
远程登录时找不到显示器
xrdp 或者 ssh 远程登录执行脚本时,窗口相关命令可能会提示找不到显示器。
可以在自动化脚本中设置以下环境变量1
2os.environ['DISPLAY'] = ':0'
os.environ['XAUTHORITY'] = '/home/<your-name>/.Xauthority'
过滤没必要的截图日志
gnome-screenshot 截图时会产生一些无用日志1
2** Message: 17:36:31.888: Unable to use GNOME Shell's
builtin screenshot interface, resorting to fallback X11.
新建一个 gnome-screenshot
文件,赋予执行权限,放到 PATH 环境变量中比 /usr/bin
靠前的路径1
2
exec /usr/bin/gnome-screenshot "$@" >> /tmp/gnome-screenshot.log 2>&1
验证码识别
pytesseract
常见的方案是 pytesseract
, 但是效果不好,识别率比较一般。
安装1
2sudo apt install tesseract-ocr
pip install pytesseract
使用1
pytesseract.image_to_string(image, config='--psm 8 -c tessedit_char_whitelist=0123456789')
ddddocr
ddddocr 是基于机器学习的验证码识别库,识别效果比较好。
这里使用 docker 安装 fastapi接口1
docker run -d -p 8000:8000 oozzbb/ddddocr-fastapi:latest
使用1
2
3
4
5
6
7
8
9
10
11
12
13
14def ocr_image(file='region.png'):
url = 'http://your-address:8000/ocr'
with open(file, 'rb') as fp:
files = {
'file': fp,
}
data = {
'probability': 'false',
'png_fix': 'false',
'charsets': '0123456789' # 验证码可能的字符列表
}
response = requests.post(url, files=files, data=data)
assert response.ok
return response.json()['data']
高效执行自动化脚本
可以在宿主机远程调用自动化脚本,并且脚本执行完成后挂起虚拟机1
2
3
4
5
6
7
8
9
10HOST=your-name@vm-ip-address
VMID=109 # pve 虚拟机id
qm resume $VMID # 唤醒虚拟机
sleep 2
ssh $HOST "SOME_VAR=foobar python your-script.py" # 执行脚本
sleep 1
qm suspend $VMID # 关闭虚拟机
其他有用的函数
1 | # 切换窗口到前台 |
使用感受
PyAutoGUI 是基于图像而不是图型控件来识别目标,没有确认反馈。
相比于网页自动化的 Selenium 就感觉落后些了。
当然,Windows 平台有 pywinauto
支持控件识别,但我不咋熟悉。
总之,PyAutoGUI 就像手枪,虽然比较简陋,但还是很直观的,执行简单的任务也够用了。
注意事项
- 自动化代码中不要编码用户名密码相关信息,建议用环境变量传入
- 不要轻易调整系统的 dpi(建议设为1.0) 和分辨率,可能导致图片无法识别
- xfce 对 wine 应用的兼容性似乎不好,wine 文件保存对话框被可能被反复触发,原因不明。