PyWinAuto 自动化(一)

  在介绍 pywinauto 前,先说一下这个工具的使用方法,就是如何去操作目标应用程序,第一步:实例化要操作的进程,得到 Application 对象;跟 App 自动化一样,window 上面有很多应用程序,先指定要操作哪个程序。第二步:选择窗口,得到一个 WindowSpecification 对象;应用程序打开,就是一个窗口,进入到这个窗口,就能获取当前窗口的元素信息。第三步:基于 WindowSpecification 对象,定位具体的控件(元素)。第四步:对控件执行相应的操作。

  使用之前先安装该工具,很简单,cmd命令行输入:pip install pywinauto 即可。

  基于上面的思路,就可以开展自动化工作了。首先获取 Application 对象,有2种方式:1、启动一个应用程序;2、直接连接已经打开的应用程序。在这之前,要确定当前应用程序的的开发技术,要不然无法获取程序信息。pywinauto 支持 win32(MFC、VB6、VCL等开发语言) 和 MS UI Automation API(WinForms、WPF、Store apps QT5、浏览器),默认是 win32。那么,怎么才能知道当前应用程序使用哪种开发技术,这里推荐2款工具:inspect.exeAccessibility Insights。以 inspect.exe 为例,打开该工具,左上角使用 UI Automation,如果有相关信息,就是uia ,如果拒绝链接,就是win32。这类工具网上很多,如果找不到,可以找我要。

  也可以通过 find_elements() 方法获取应用窗口,该方法适合已经打开的窗口,不传参数,默认查找所有窗口,关键字参数见下方介绍,可以缩小范围。这样在使用 connect() 方法获取 Application 对象就比较方便。

from pywinauto import Application,findwindows
findwindows.find_elements()
==> [ <win32_element_info.HwndElementInfo - '无标题 - Notepad', Notepad, 854118>, <win32_element_info.HwndElementInfo - 'PyWinAuto - xxx@163.com - 印象笔记', Qt5152QWindowIcon, 788708> ]

findwindows.find_window(title="无标题 - Notepad")
==> 854118

  启动一个新的应用:app=Application(backend=“uia”).start(‘notepad.exe’),start 方法传入要打开的应用程序,如果找不到,就要输入全路径。这里就是打开了本机的记事本。

  连接已经打开的应用:app=Application(backend=“uia”).connect(title_re=‘.印象笔记.’),connect 方法连接已经打开的程序,有好几种方式,我介绍比较常用的:

process可以使用pid 进行绑定;
handle可以使用窗口句柄绑定;
path可以使用程序路径绑定;
title_re根据窗口标题名字绑定;
class_name根据窗口类名绑定;

  这里我比较喜欢用 title_re 参数连接应用程序,每个应用程序打开,在左上角都会有一个 titile,title_re 是利用正则匹配窗口,也可以直接使用 title 参数,但是,如果名字比较长,显得麻烦;使用 process、handle、calss_name 去连接,还需要去查,不如 title_re 方便。具体看情况使用。

  到这里,就可以获取到一个 Application 对象,然后可以操作该对象的方法,例如:

  • app.process:获取进程 id;
  • app.kill:强制关闭该应用程序;
  • app.top_window():返回顶层窗口对象;.dump_tree() 方法可以获取当前窗口结构信息,跟后文的 print_control_identifiers() 方法一样;
  • app.windows():获取当前应用所有窗口;
  • app.cpu_usage():返回指定秒数期间的CPU使用百分比;
  • app.wait_cpu_usage_lower(threshold=2.5, timeout=None, usage_interval=None):等待进程CPU使用率百分比小于指定的阈值threshold.
  • app.is_process_running():当前进程是否运行中;

  有了Application对象,还需要获取窗口对象,app.windows() 是获取所有窗口对象,返回一个列表,包含窗口的标题、类、句柄,这些信息对于连接到具体的窗口很有用。获取窗口对象:app.window(title=“DingTalk”),也可以使用 app[“Dialog”],我比较喜欢使用 window()方法,该方法有很多关键字参数可用:

class_name类名;
title控件标题,就是inspect 中的name;
auto_idinspect 中的automationId 属性;
control_typeinspect 中 LocalizedControlType属性(不是中文,是英文,control_type值有MenuBar、Button、Edit、MenuItem等);
title_retitle正则匹配;
best_match模糊匹配title;
handleNativeWindowHandle;

  这里的关键字参数,不仅在 window() 方法可用,在 connect() 方法、child_window() 方法中也可以使用,还可以联合使用,大家可以多试试。


# 获取钉钉窗口对象
dlg = app.window(title="钉钉")
dlg = app.window(class_name="Dialog")
dlg = app["Dialog"]

  窗口对象WindowSpecification 有一些常用的方法,如下:

  • dlg.maximize():窗口最大化;
  • dlg.minimize():窗口最小化;
  • dlg.restore():还原窗口;
  • dlg.get_show_state():获取窗口显示状态,最大化是1,正常是0;
  • dlg.close():关闭窗口;
  • dlg.rectangle():获取窗口坐标;
  • draw_outline(colour=“red”) :给窗口/控件加外框,便于识别;
  • exists(timeout=None, retry_interval=None):判断窗口是否存在;
  • wait(state, timeout=None, retry_interval=None):等待窗口;
  • wait_not(state, timeout=None, retry_interval=None):等待窗口;
  • dlg.print_control_identifiers(depth=None):获取窗口结构信息,depth 指定结构深度;除了通过工具获取控件(元素)信息,这个方法也是重要的途径,工作中也会经常用到。

  通过窗口对象可以获取当前窗口的结构信息,然后就可以获取窗口中的控件,方法如下:

  • dlg[“控件名称”],这种方式常用,但是注意中文乱码问题。
  • dlg.xxx,这种方式不建议,如果控件的名称中间有空格,那就不好使了。
  • dlg.child_window(title=,best_match=,…),上面的常见关键字参数都可以使用,获取窗口指定控件(递归查找)found_index 指定索引,如果有多个相同的控件,可以加该参数。我常用这种方式。
  • dlg.children():获取 窗口/控件 子元素(直系),返回一个list;
  • dlg.descendants() 查找所有符合条件的子孙元素,返回一个list,可以添加条件缩小范围;
app = Application("uia").connect(title="钉钉")
dlg = app.window(title="钉钉")

search = dlg.child_window(title="搜索", control_type="Edit")
search.click_input()
search.type_keys("Alan")
time.sleep(1)
SendKeys("{ENTER}")

chat = dlg.child_window(control_type = "Document",class_name="Chrome_RenderWidgetHostHWND")
chat.wait("ready",10,1)

time.sleep(2)
content = chat.descendants(control_type = "ListItem")

  当然,APP、UI里面的层级定位、下标定位也是支持的;
  层级定位
在这里插入图片描述

new_dlg = dlg.child_window(best_match="Form")
new_dlg.child_window(best_match="Edit").set_text("123")

  下标定位

# 定位 记事本 输入框,并输入内容,跟上图一样

dlg.children()[0].children()[0].type_keys("层级定位")

  在关键字参数中,介绍了 control_type,在 inspect.exe 工具显示的是中文,但是不能使用,要使用英文类型,这个参数也常用,所以给大家列举一下常见的控件类型;

Button按钮控件
Calendar日历控件,例如日期选取器
CheckBox复选框控件
ComboBox组合框控件
Custom标识一个控件,该控件不属于已定义的控件类型之一
DataGrid数据网格控件
DataItem数据项控件
Document文档控件
Edit编辑控件,例如一个文本框
Group其他控件的容器的组控件
Header标题控件,它是一个用作信息的行和列标签的容器
HeaderItem标题项,它是信息的行或列的标签
Hyperlink超链接控件
Image图像控件
List列表控件,例如列表框
ListItem列表项控件,它是列表控件的子项
Menu菜单控件,例如应用程序窗口中的一个顶级菜单
MenuBar菜单栏控件,它通常包含一组顶级菜单
MenuItem菜单项控件
Pane格控件
ProgressBar进度条控件,该控件以可视方式指示一个长时间操作的进度
RadioButton单选按钮控件,这种选择机制只允许在组中选择一项
ScrollBar滚动条控件,例如应用程序窗口中的滚动条
Separator分隔符
Slider滑块控件
Spinner微调控件
SplitButton拆分按钮,该按钮将执行默认操作,并且还可以扩展到其他可能操作的列表。
StatusBar状态栏控件
Tab选项卡控件
TabItem选项卡项控件,它代表选项卡控件的一页
Table
Text编辑控件,例如一个文本框或多格式文本框
Thumb标识滚动条中可拖到不同位置的控件
TitleBar窗口上的标题栏
ToolBar工具栏,例如应用程序窗口中包含一组命令按钮的控件
ToolTip工具提示控件,将指针移动到一个控件上方时或有时使用键盘 Tab 键切换到一个控件时将出现此信息窗口。
Tree树控件
TreeItem标识 TreeItem 控件中的一个节点
Window包含子对象的窗口框架

  有关控件的属性及操作在下文一一讲解,谢谢大家的关注!

  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值