1. 前言
大家好钦扭,我是安果!
上一篇文章善玫,聊到 PC 端的一種自動化方案:WinAppDriver
有小伙伴后臺給我留言洒敏,說「 pywinauto 」作為 WinAppDriver 的替代方案矗蕊,也能完美完成 PC 端的自動化
2. 介紹
Pywinauto,完全由 Python 構(gòu)建的一個模塊杠河,可以用于自動化 Windows 上的 GUI 應(yīng)用程序
同時碌尔,它支持鼠標(biāo)浇辜、鍵盤操作,在元素控件樹較復(fù)雜的界面七扰,可以輔助我們完成自動化操作
項(xiàng)目地址:https://github.com/pywinauto/pywinauto
支持的應(yīng)用為下面 2 大類:
-
Win32 API
包含 MFC奢赂、VB6、VCL颈走、simple WinForms controls and most of the old legacy apps
-
MS UI Automation
包含 WinForms膳灶、WPF、Store apps立由、Qt5, browsers
其中
win32 API 的 backend 為「 win32 」
MS UI Automation 的 backend 為「 uia 」
3. 元素控件
和 WinAppDriver 類似轧钓,在編寫自動化腳本之前,我們需要先獲取元素控件的各類屬性值
獲取元素控件有 2 種方式:
窗口內(nèi)置方法
檢查工具
其中
窗口對象內(nèi)置的 2 個方法都可以打印出當(dāng)前頁面的元素控件樹
# 窗口對象中內(nèi)置方法锐膜,打印窗體內(nèi)所有元素控件
# 方式一:
窗體對象.print_control_identifiers()
# 方式二
窗體對象.dump_tree()
常用的檢查工具也包含 2 種毕箍,分別是:Inspect.exe、Spy++
4. 實(shí)戰(zhàn)一下
在實(shí)戰(zhàn)之前道盏,我們先安裝依賴包 pywinauto
# 安裝依賴
pip3 install pywinauto
接下來而柑,我們還是以上篇文章中的例子來講解完整的實(shí)現(xiàn)過程
4-1 打開微信客戶端
首先,通過檢查工具判斷應(yīng)用的 backend 屬性值荷逞,PC 端微信的 backend 為「 uia 」
然后媒咳,實(shí)例化一個「 Application 」類
最后,使用該對象內(nèi)置的函數(shù)創(chuàng)建一個應(yīng)用對象
import pywinauto
from pywinauto.application import Application
# 獲取應(yīng)用對象
# 三種方式任選一種
# 方式一:應(yīng)用進(jìn)程pid(連接)
app = Application(backend='uia').connect(process=pid)
# 方式二:應(yīng)用完整路徑(連接)
app = Application(backend='uia').connect(path="D:\Program Files (x86)\Tencent\WeChat\WeChat.exe")
# 方式三:打開應(yīng)用(打開)
app = Application(backend='uia').start('D:\Program Files (x86)\Tencent\WeChat\WeChat.exe')
需要指出的是种远,獲取應(yīng)用對象有上面 3 種方式涩澡,可以按需使用
4-2 獲取窗體對象
通過檢查工具獲取窗體的屬性列表,然后使用應(yīng)用對象 + 窗體屬性獲取微信首頁的窗體對象
實(shí)現(xiàn)代碼如下:
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 切換到聊天列表
獲取左側(cè)聊天切換按鈕坠敷,獲取其坐標(biāo)位置妙同,模擬點(diǎn)擊進(jìn)入到聊天列表頁面
from pywinauto import mouse
def __get_element_postion(self, element):
"""獲取元素的中心點(diǎn)位置"""
# 元素坐標(biāo)
element_position = element.rectangle()
# 算出中心點(diǎn)位置
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、獲取左側(cè)【聊天】切換元素
chat_list_element = self.weixin_pc_window.child_window(title="聊天", control_type="Button")
# 2膝迎、點(diǎn)擊進(jìn)入到聊天列表
mouse.click(button='left',
coords=self.__get_element_postion(chat_list_element))
4-4 進(jìn)入聊天頁面粥帚,輸入內(nèi)容并發(fā)送
獲取「 文件聊天助手 」元素,點(diǎn)擊進(jìn)入到聊天頁面限次,找到輸入框元素茎辐,使用內(nèi)置方法輸入內(nèi)容,最后使用鍵盤模擬點(diǎn)擊「 Enter 」鍵掂恕,發(fā)送消息
from pywinauto import mouse
# 3拖陆、點(diǎn)擊【文件傳輸助手】進(jìn)入到聊天頁面
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)
# 輸入內(nèi)容
edit_element.type_keys("星安果")
# 使用鍵盤模擬回車依啰,即:發(fā)送
send_keys('{ENTER}')
4-5 釋放資源
完成操作后,可以調(diào)用應(yīng)用對象的「 kill() 」函數(shù)關(guān)閉進(jìn)程店枣,釋放掉資源
def teardown(self):
"""釋放資源"""
# 結(jié)束進(jìn)程速警,釋放資源
self.app.kill()
5. 最后
上例中使用 pywinauto 完成了一個簡單的發(fā)送消息的自動化步驟
實(shí)際項(xiàng)目中叹誉,結(jié)合鼠標(biāo)、鍵盤可以實(shí)現(xiàn)很多復(fù)雜場景的自動化闷旧,對這部分有興趣的可以點(diǎn)擊文末的「 閱讀原文 」去了解
pywinauto 和 WinAppDriver 都能很好的完成 PC 端的自動化长豁,但是由于 WinAppDriver 支持 Appium,在腳本語法簡潔性方面可能更有優(yōu)勢
文中的所有源碼我已經(jīng)上傳到公眾號后臺忙灼,關(guān)注公眾號「 AirPython 」后匠襟,回復(fù)關(guān)鍵字「 winauto 」獲取完整源碼
如果你覺得文章還不錯,請大家 點(diǎn)贊该园、分享酸舍、留言 下,因?yàn)檫@將是我持續(xù)輸出更多優(yōu)質(zhì)文章的最強(qiáng)動力里初!