在 Linux 虚拟机中使用 PyAutoGUI 做自动化
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 对显卡有要求,虚拟机不方便处理。
睡眠后时间不对
虚拟机睡眠唤醒后时间没有更新,不知道为什么没有触发时间更新。
目前只能通过强行同步来解决
在脚本里执行同步命令
1 | # 和阿里云ntp服务器同步 |
或者,理论上可以通过虚拟机中的 systemd-suspend hook,或者 pve hookscript 来解决(没试成功)
PyAutoGUI 使用技巧
远程登录调试
pve 默认图片控制台不太方便,不能复制粘贴,所以使用远程登录调试
由于系统使用 x11 环境,这里使用 xrdp 作为远程服务端。
如果以后更新到 wayland,可以使用 gnome-remote-desktop。
1 | sudo apt update |
远程登录时找不到显示器
xrdp 或者 ssh 远程登录执行脚本时,窗口相关命令可能会提示找不到显示器。
可以在自动化脚本中设置以下环境变量
1 | os.environ['DISPLAY'] = ':0' |
过滤没必要的截图日志
gnome-screenshot 截图时会产生一些无用日志
1 | ** Message: 17:36:31.888: Unable to use GNOME Shell's |
新建一个 gnome-screenshot 文件,赋予执行权限,放到 PATH 环境变量中比 /usr/bin 靠前的路径
1 |
|
验证码识别
pytesseract
常见的方案是 pytesseract, 但是效果不好,识别率比较一般。
安装
1 | sudo apt install tesseract-ocr |
使用
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 | def ocr_image(file='region.png'): |
高效执行自动化脚本
可以在宿主机远程调用自动化脚本,并且脚本执行完成后挂起虚拟机
1 | HOST=your-name@vm-ip-address |
其他有用的函数
1 | # 切换窗口到前台 |
使用感受
PyAutoGUI 是基于图像而不是图型控件来识别目标,没有确认反馈。
相比于网页自动化的 Selenium 就感觉落后些了。
当然,Windows 平台有 pywinauto 支持控件识别,但我不咋熟悉。
总之,PyAutoGUI 就像手枪,虽然比较简陋,但还是很直观的,执行简单的任务也够用了。
注意事项
- 自动化代码中不要编码用户名密码相关信息,建议用环境变量传入
- 不要轻易调整系统的 dpi(建议设为1.0) 和分辨率,可能导致图片无法识别
- xfce 对 wine 应用的兼容性似乎不好,wine 文件保存对话框被可能被反复触发,原因不明。