4. 基于选择器的UI元素定位:CSS选择器、XPath选择器、UI Automation选择器

说到UI元素定位,选择器这东西,我刚开始做RPA时也踩过不少坑。你想想看,一个按钮在页面上,你怎么告诉程序「就是它」?靠坐标?那换个分辨率就完蛋。靠图片?换个主题就认不出来了。所以,选择器才是正道。

这一章,我重点讲三种最常用的选择器:CSS选择器、XPath选择器,还有Windows桌面端专用的UI Automation选择器。每种我都会结合自己的实战经验来讲。

4.1 CSS选择器:Web自动化的首选

CSS选择器,说白了就是通过HTML元素的样式特征来定位。我个人习惯在Web自动化中优先用它,为什么?因为浏览器对CSS的解析速度最快,而且写法简洁。

核心要点:CSS选择器基于元素的id、class、标签名、属性等特征进行匹配。

举个例子,假设页面上有个登录按钮:

<button id="loginBtn" class="btn-primary" data-action="login">登录</button>

用CSS选择器定位它,可以这样写:

#loginBtn                    // 通过id定位
.btn-primary                 // 通过class定位
button[data-action="login"]  // 通过属性定位
button.btn-primary           // 标签+class组合

我在项目中遇到过一个问题:一个页面有几十个按钮,class都差不多,唯独data属性不同。用CSS的属性选择器,一行代码就搞定了,比XPath快得多。

我的小技巧:在Chrome开发者工具里,按Ctrl+F,输入CSS选择器,能实时验证是否匹配到目标元素。这招我用了好多年,效率极高。

4.2 XPath选择器:复杂场景的救星

XPath,说实话,一开始我觉得它挺啰嗦的。但后来发现,有些场景非它不可。比如,你要找一个「包含某段文本」的元素,或者要定位「某个元素后面的兄弟元素」,CSS就力不从心了。

XPath有两种写法,我简单说一下:

类型 写法 特点
绝对路径 /html/body/div[1]/button 从根节点开始,一写就长,一改就废
相对路径 //button[@id='loginBtn'] 从任意位置开始,灵活,我推荐用这个

举个例子,你要找一个文本为「确认删除」的按钮:

//button[text()='确认删除']

或者找一个包含「删除」二字的:

//button[contains(text(), '删除')]

注意:我曾经因为XPath写得太绝对,结果页面结构一改,脚本全崩了。后来我养成了习惯:能用相对路径,绝不用绝对路径。能用id或class,就别依赖文本内容。

还有一个坑,我提一下:XPath的索引是从1开始的,不是0。我第一次用的时候,写了个[0],找了半天找不到元素,后来才反应过来。嗯,这个细节容易忽略。

4.3 UI Automation选择器:桌面应用的利器

做RPA,不可能只跟网页打交道。Windows桌面应用怎么办?这时候就要用UI Automation(UIA)选择器了。

UIA是微软提供的一套UI自动化框架。它把每个界面元素都抽象成一个「控件」,每个控件都有一些属性,比如Name、AutomationId、ControlType等。

举个例子,一个记事本的菜单项「文件」:

<MenuItem Name="文件" AutomationId="MenuItemFile" ControlType="MenuItem"/>

用UIA选择器定位,可以这样写:

ControlType=MenuItem;Name=文件
ControlType=MenuItem;AutomationId=MenuItemFile

我建议你用AutomationId来定位,因为它通常不会变。Name可能会因为语言切换而变化,比如中文系统叫「文件」,英文系统叫「File」,那就麻烦了。

避坑指南:我曾经做一个财务软件的自动化,那个软件的所有按钮都没有AutomationId,Name还经常变。后来我用了一个工具叫Inspect.exe(Windows SDK自带的),把整个UI树扒下来,发现可以用ControlType+Index组合来定位。虽然麻烦点,但至少稳定。

4.4 三种选择器的对比与选择

说了这么多,到底什么时候用哪种?我整理了一个表格,你一看就明白:

场景 推荐选择器 原因
Web页面,元素有id或class CSS选择器 速度快,写法简单
Web页面,需要根据文本定位 XPath CSS不支持文本匹配
Web页面,需要定位父/子/兄弟元素 XPath 轴操作(parent/child/following-sibling)很强大
Windows桌面应用 UI Automation 专门为桌面UI设计的
跨平台(Web+桌面混合) 根据具体平台切换 没有万能药,灵活切换才是王道

你想想看,如果每个场景都用同一种选择器,那肯定会有力不从心的时候。我个人的习惯是:Web优先CSS,搞不定再上XPath;桌面应用就用UIA,实在不行再考虑图像识别。

总结一下:选择器没有好坏之分,只有合不合适。关键是理解每种选择器的原理和适用场景,然后根据实际情况灵活选用。嗯,这一章的内容就到这里,下一章我们聊聊动态元素的处理技巧。