大家好,我是安果!
上一篇文章,聊到 PC 端的一种自动化方案:WinAppDriver
有小伙伴后台给我留言,说「pywinauto」作为 WinAppDriver 的替代方案,也能完美完成 PC 端的自动化
Pywinauto,完全由 Python 构建的一个模块,可以用于自动化 Windows上的 GUI 应用程序
同时,它支持鼠标、键盘操作,在元素控件树较复杂的界面,可以辅助我们完成自动化操作
项目地址:https://github.com/pywinauto/pywinauto
支持的应用为下面 2 大类:
其中
win32 API 的backend 为「win32」
MS UI Automation 的 backend 为「uia」
和WinAppDriver 类似,在编写自动化脚本之前,我们需要先获取元素控件的各类属性值
获取元素控件有 2 种方式:
其中
窗口对象内置的 2 个方法都可以打印出当前页面的元素控件树
- # 窗口对象中内置方法,打印窗体内所有元素控件
- # 方式一:
- 窗体对象.print_control_identifiers()
-
- # 方式二
- 窗体对象.dump_tree()
-
常用的检查工具也包含 2 种,分别是:Inspect.exe、Spy++
在实战之前,我们先安装依赖包 pywinauto
- # 安装依赖
- pip3 install pywinauto
-
接下来,我们还是以上篇文章中的例子来讲解完整的实现过程
4-1打开微信客户端
首先,通过检查工具判断应用的 backend 属性值,PC 端微信的 backend 为「uia」
然后,实例化一个「Application」类
最后,使用该对象内置的函数创建一个应用对象
- import pywinauto
- from pywinauto.application import Application
-
- # 获取应用对象
- # 三种方式任选一种
- # 方式一:应用进程pid(连接)
- app = Application(backend='uia').connect(process=pid)
-
- # 方式二:应用完整路径(连接)
- app = Application(backend='uia').connect(path="D:\Program Files (x86)\Tencent\WeChat\WeChat.exe")
-
- # 方式三:打开应用(打开)
- app = Application(backend='uia').start('D:\Program Files (x86)\Tencent\WeChat\WeChat.exe')
-
需要指出的是,获取应用对象有上面 3 种方式,可以按需使用
4-2 获取窗体对象
通过检查工具获取窗体的属性列表,然后使用应用对象 + 窗体属性获取微信首页的窗体对象
实现代码如下:
- from pywinauto.win32functions import SetFocus
-
- # 获取窗口对象
- # 通过title及ClassName获取窗体对象
- self.weixin_pc_window = self.app.window(title=u"微信", class_name="WeChatMainWndForPC")
-
- self.weixin_pc_window.set_focus()
-
4-3切换到聊天列表
获取左侧聊天切换按钮,获取其坐标位置,模拟点击进入到聊天列表页面
- from pywinauto import mouse
-
- def __get_element_postion(self, element):
- """获取元素的中心点位置"""
- # 元素坐标
- element_position = element.rectangle()
- # 算出中心点位置
- center_position = (int((element_position.left + element_position.right) / 2),
- int((element_position.top + element_position.bottom) / 2))
- return center_position
-
- def start(self):
- # 1、获取左侧【聊天】切换元素
- chat_list_element = self.weixin_pc_window.child_window(title="聊天", control_type="Button")
- # 2、点击进入到聊天列表
- mouse.click(button='left',
- coords=self.__get_element_postion(chat_list_element))
-
4-4进入聊天页面,输入内容并发送
获取「 文件聊天助手 」元素,点击进入到聊天页面,找到输入框元素,使用内置方法输入内容,最后使用键盘模拟点击「 Enter 」键,发送消息
- from pywinauto import mouse
-
- # 3、点击【文件传输助手】进入到聊天页面
- file_helper_element = self.weixin_pc_window.child_window(title="文件传输助手", control_type="ListItem")
-
- mouse.click(button='left',
- coords=self.__get_element_postion(file_helper_element))
- # 4、获取输入框元素,模拟输入
- edit_element = self.weixin_pc_window.child_window(title=r"输入", control_type="Edit")
-
- sleep(2)
- # 输入内容
- edit_element.type_keys("星安果")
- # 使用键盘模拟回车,即:发送
- send_keys('{ENTER}')
-
4-5释放资源
完成操作后,可以调用应用对象的「kill()」函数关闭进程,释放掉资源
- def teardown(self):
- """释放资源"""
- # 结束进程,释放资源
- self.app.kill()
-
上例中使用 pywinauto 完成了一个简单的发送消息的自动化步骤
实际项目中,结合鼠标、键盘可以实现很多复杂场景的自动化,对这部分有兴趣的可以点击文末的「阅读原文」去了解
pywinauto 和 WinAppDriver 都能很好的完成 PC 端的自动化,但是由于 WinAppDriver 支持 Appium,在脚本语法简洁性方面可能更有优势
文中的所有源码我已经上传:源码:https://github.com/xingag/test_auto/blob/master/pc/Pywinauto%E5%AE%9E%E4%BE%8B.py