1297 字
6 分钟
UI自动化之Py Uiautomation

RPA开发一些网银页面自动化流程时,会出现一些情况,企业网银使用U盾的登陆页面有时会包含一些特殊的密码控件,使得他们的页面中的密码框元素不会显示在网页中,我们使用F12调试工具选中的时候发现无法选中,页面中的其他元素都可以直接选中,但是密码框那边是不存在的,查找网页中的元素也找不到密码框的元素,这使得传统的网页自动化工具类似于Selenium无法正常点击和输入。

密码框无法点击示例

上面的示例图可以看到,唯独密码框部分是没有选中的,查看网页源代码发现也是没有密码框的input或者其他元素。

于是激活密码框和输入也成了一个难题。

#

在技术攻坚时了解到了Uiautomation这一个UI自动化工具。它支持自动化Win32MFCWPFModern UI (Metro UI)QtIEFirefoxChrome以及基于Electron开发的应用程序。这个是它官方说的支持情况,其实不需要知道这么多,只需要知道它可以做UI自动化控制I/O程序就行了,常用的也就是Win32桌面和一些网页端的UI控制。

微软做了一个应用程序inspect用来方便读取整个桌面/应用程序的UI框架,它可以直观的展示现在你所在屏幕内容的树形结构,而且显示了它们的各个属性,方便UIA进行定位。

提供一个下载地址: Inspect.exe

再放一个程序的展示图,可以下载到本地琢磨琢磨。

inspect

应用左边显示的是整个屏幕显示内容的树形结构,右边显示的是特定桌面元素的各项属性。

正片开始#

好了准备工作就绪的话,现在就可以开始操作了,先捋起袖子不要影响我们敲代码。鼠标再换成无线的否则拖拖拉拉不舒服。

回到上面的问题场景,我没法通过比如Xpath定位使用Selenium类似的工具进行元素的定位和点击,因为网页中根本不存在这个元素,但是它既然显示在你的桌面屏幕上,那么它就是一个桌面元素,所以我们就可以对他进行定位。再通过对他的点击操作实现目标。

uia识别

可以看到,这个密码框是一个Pane桌面元素,所以就可以很自然的定位到它在对他进行一些操作。

然后,我们也可以看到这个元素是没有Name属性的,最多的定位是可以通过Name属性进行定位的,所以需要找到一个可以轻松定位的元素,再通过相对位置一步一步找到这个密码输入框。

因为涉及企业网银的一些信息,这里不具体一步步展示,打个比方,在这个网页上的登录按钮它的元素元素类别是ButtonName属性值为登录(事实上确实是这样),于是我们可以通过一下代码对他进行一个简单的定位。

import uiautomation as uia

# 你可以这么写
login_btn = uia.ButtonControl(Name="登录", [maxSearchDepth])

# 如果你还想点击
login_btn = uia.ButtonControl(Name="登录", [maxSearchDepth]).click()

稍作解释: ButtonControl表示是按钮元素类型,还有很多比如ExitControlTextControl Name是定位的根据,还有很多比如ClassNameAutomationId searchDepth表示搜索深度,表示在树形目录下的搜索深度

可以去看函数的源码做更多的了解,现在我要继续解决一下问题。

现在我打个比方,上面我的密码框的位置,是在登录按钮的父元素下一个同级元素第三个子元素第一个子元素,好像说的有点花里胡哨,不是的,我是要介绍一下层级定位的各个方法。

现在我们可以开始寻找这个令人恼火的密码框了。

import uiautomation as uia

# 登录按钮
login_btn = uia.ButtonControl(Name="登录", [maxSearchDepth])

fuck_pwd_input = login_btn.GetParentControl()
                          .GetNextSiblingControl()
                          .GetChildren()[2]
                          .GetFirstChildControl()
if fuck_pwd_input.Exists(maxSearchSeconds=10):
    # 激活它
    fuck_pwd_input.click()
    # 输入密码
    fuck_pwd_input.SendKeys("{my_password}", [waitTime])

做一些解释: Exists表示搜索时间,参数为maxSearchSeconds SendKeys表示输入,waitTime表示输入前等待时间,同样click函数也又这个参数

这样问题就解决了;只是上面一级一级搜索的过程,我相信对照中文说明或者英文的字面意思都是看的明白的。

不要依赖#

结合Uiautomation工具能够弥补网页端自动化元素定位的一些缺陷,但是其实也是有问题的,这个工具不能够非常及时的刷新桌面应用程序,在一些场景下,桌面元素可能发生变动但是它并没有很及时的更新树结构,所以很多时候会发现使用UIA去定位的时候返回为空,并没有成功的找到元素。

UI自动化之Py Uiautomation
https://blog.kimbleex.top/posts/2025-06-13-uiautomation/uiautomation/
作者
Kimbleex
发布于
2025-06-13
许可协议
CC BY-NC-SA 4.0