ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

UiPath网页自动化:获取元素集合实现遍历点击的完整指南

UiPath网页自动化:获取元素集合实现遍历点击的完整指南 做 RPA 项目尤其是网页自动化最常被问到的需求之一就是这个把页面上同一类元素一个一个点过去。比如逐条审批流程、逐个打开搜索结果、逐项点击菜单确认页面状态。拿 UiPath 来说用鼠标录制一个点击很简单但面对动态数量的元素录制这条路就走不通了。本文就围绕“UIPath 获取网页元素做遍历点击的实现”展开把获取元素集合、写动态 Selector、循环点击、处理各种意外情况的完整思路拆开讲一遍。写这篇文章的起因是我经手过好几个 UiPath 项目前期需求描述都是“把这个列表里的内容全部点一遍把详情页数据存下来”听起来像是一个 Click 活动的事实际做起来牵扯到元素集合的获取、Selector 的稳定性、页面上下文切换还有各种运行时异常。把这段经验整理出来希望能帮到正在做类似需求的同学尤其是刚接触 UiPath 网页自动化的朋友。1. 为什么页面自动化里最常被点名的需求是“遍历点击”1.1 一个每天都在重复的场景先描述一个最典型的场景某个后台管理系统的待办审批列表每天都有几十条新记录。业务人员需要一条条点进详情页点“通过”或“驳回”再返回列表处理下一条。人工操作一天下来非常枯燥而且容易漏点。用 UiPath 做自动化时最直接的想法就是录一个点击的序列先点第一行处理完返回再点第二行……问题在于列表里的条数每天不一样行号也每天都在变。如果流程里写死“点击第三行”那天只有两条记录就会出错有三十条记录时又只能处理前三条。要真正解决这个问题必须让流程自己去发现“当前页面上有多少个可点击的元素”再逐个去处理。这个需求就是典型的遍历点击。1.2 遍历点击与普通点击的本质差异普通点击是“我知道我要点哪个元素所以我告诉 UiPath 这个元素的特征”。比如某个按钮有固定的 id 或者固定的文本UiPath 直接根据 Selector 定位过去一次点击就完事。遍历点击则不一样。它面对的是一个元素集合集合的大小、顺序、内容都可能动态变化。流程要做的是先获取这个集合再通过循环挨个处理。两者的底层差异决定了方案的完全不一样普通点击可以硬编码 Selector遍历点击一般需要通配符或动态 Selector。普通点击不需要考虑“元素是否存在”遍历点击必须考虑集合为空、元素被重新渲染等边界情况。普通点击完后流程就结束了遍历点击中每次点击后页面可能跳转流程还需要负责“回到列表页继续下一次点击”。所以什么时候该用遍历点击只要满足“同类元素 数量动态 每个元素都需要逐个操作”这三个特征就是一个适合遍历点击的场景。反过来如果列表数量固定、内容不变那老老实实录个固定点击反而更省事没必要强行上循环。1.3 什么时候该用遍历点击什么时候不该用这点很多人会忽略但我在项目评审时几乎每次都会提。遍历点击虽然灵活也有它的成本和风险每次循环都要重新定位元素、等待页面加载运行速度明显比普通点击慢而且页面只要一刷新之前获取的元素引用就可能失效需要额外处理。如果页面的元素数量固定比如一个固定的导航栏只有五个菜单项那就别用遍历如果元素的顺序和数量都稳定用几个独立的 Click 活动按顺序执行维护起来更直观。如果数量经常变、内容经常变、甚至不同用户的待办数量都不一样就必须用遍历点击。先判断场景归属再动手写流程能省掉后面很多不必要的麻烦。2. 获取网页元素集合先搞懂 Find Children 和 Get Ui Elements2.1 Find Children经典玩法在 UiPath 里获取多个网页元素最常见的方式是“Find Children”活动。这个名字可能容易让人误解它并不是“查找子级”那么简单它的作用是在你指定的某个容器元素比如列表的 div、表格的 tbody、菜单的 ul下筛选出所有符合条件的子元素。Find Children 的参数有讲究。它有一个“作用域”的概念你需要先指定一个容器作为锚点然后在容器内部按 Selector 过滤子元素。输出是一个 UiElement 数组。例如一个待办列表ul classtodo-list li classtodo-item>html appchrome title待办中心 / webctrl tagBUTTON typebutton txt审批 /它表达的意思是在 Chrome 浏览器、标题为“待办中心”的页面里找那个标签是 BUTTON、类型是 button、文本是“审批”的按钮。调试 Selector 时我推荐直接用 UiPath 的“UI Explorer”工具。安装扩展后在活动面板里点“拾取元素”旁边的小箭头就能打开 UI Explorer里面可以看到页面的 UI 树还能手动修改某个节点的属性实时测试你的 Selector 能不能匹配到目标元素。改 Selector 的时候右下角一般会显示当前匹配到的元素数量这个数字非常有用。如果你填的通配符写错了比如属性名拼错匹配数会直接变成 0当场就能发现。3.2 通配符怎么写才不容易误伤遍历点击场景里最常用的技巧就是给 Selector 加通配符。UiPath 的通配符和文件通配符类似*表示匹配任意多个字符?表示匹配任意一个字符举个例子列表项如果 class 是动态的比如有时是todo-item active有时是todo-item pending那 Selector 里可以写成classtodo-item*这样不管后面跟什么状态都能匹配到。又比如按钮的文本在“通过”“驳回”“查看详情”之间变化但都包含“批”字可以写成txt*批*不过这里有个重点别为了“全”把 Selector 写得太宽。比如你写classitem也许页面上还有别的模块也叫 item一下就把无关元素捞进来了。正确做法是给 Selector 增加约束条件既要 class 匹配又要 tag 匹配必要时再加上父级节点限定。多个条件同时满足才能保证筛出来的元素是我们要的那一拨。3.3 缩小作用域用父容器当锚点Selector 写得再稳也架不住页面上有大量相似结构。比如页面左侧菜单和右侧面板里都有 class 为list-item的元素只靠单个元素的特征区分不出来。这时候就要靠“作用域”来帮忙。Find Children 的设计思路正是如此先可靠地定位父容器再在父容器内筛选子元素这样层级关系就锁死了。父容器即使 index 会变化但如果它有一个稳定的业务属性比如>div classapproval-container div classapproval-item>webctrl tagDIV classapproval-item /输出设为一个名为approvalItems的 UiElement 数组变量。此时approvalItems中就有了三个元素的引用。如果页面一次只显示 10 条它就只有 10 条要处理全部记录就得先考虑下一页或滚动加载的问题这个后面第五节再细聊。4.2 第二步For Each 循环里的点击安排拿到集合以后下一步是遍历。我会放一个“For Each”活动遍历类型选择UiElement遍历对象选approvalItems循环体内放一个“Click”活动。这里有一个很多新手会卡住的点Click 活动的 Target 默认是让你“拾取一个元素”而不是让你直接选一个变量。要点击当前循环项方法是把循环变量item拖到 Click 活动上或者把 Click 的 Target 类型改为“UIElement”然后选中item变量。这样循环每跑一次点击的就是当前这一个元素。如果元素没有完全显示在可视区域内点击之前最好加一个“Scroll Into View”活动参数也指向item。某些网页上元素虽然在 DOM 里但不在当前滚动区域直接 Click 会被浏览器拦截或者提示“元素不可见”。先把元素滚到视野里再执行点击成功率高很多。4.3 第三步点击后的等待与页面恢复遍历点击最容易被忽略的是点击后的“页面状态”。你点进去一个详情页页面发生了跳转或弹窗这时候直接进入下一轮循环去点击第二个元素大概率会失败因为页面已经不是刚才那个列表页了。所以循环体内通常要分成三段点击前等待目标元素就绪必要时滚动到可见位置。点击后等待详情页加载完成。具体可以用“Wait Element Appear”等待详情页上的某个特定元素出现或者用“Delay”活动给一个合理的缓冲时间。回到列表如果在详情页进行了操作需要“Browser Back”或者点击返回按钮然后再等待列表元素重新出现才可以进入下一次循环。注意一点从详情页返回之后原来的 UiElement 引用可能已经失效。如果只是返回同一条列表页元素引用偶尔还能用但只要页面有刷新保险的做法是每次循环开始时重新获取一次元素集合或者在循环开头等待列表容器重新出现。4.4 一个最小可用模板用文字描述不如给一个精简模板。以下是一个用 UiPath 活动搭建的最小可运行流程大致顺序是打开浏览器进入待办列表页。Find Element 定位列表容器container。Find Children 获取所有审批项approvalItems。For EachitemInapprovalItemsScroll Into Viewitem。Clickitem。Wait Element Appear 详情页标志元素比如保存按钮。执行详情页里的操作。返回列表页。Wait Element Appear 列表容器。日志输出“遍历完成”。这个模板本身很简单但每一步都有值得优化的空间。尤其是第 4 步里的返回操作如果详情页是打开新标签页还要加一个“切换浏览器标签页”的活动否则流程仍然停在旧页面。5. 实际项目里踩过的坑元素失效、懒加载、iframe 和弹窗5.1 页面一刷新之前拿到的 UiElement 就失效了这是遍历点击里最常见的坑。UiElement 变量本质上是对页面上一个节点的引用页面如果发生了刷新原来的引用就断了对它执行 Click 就会报错提示类似“元素不存在”或“选取器超时”。解决方法分两种思路。如果页面只是局部刷新返回列表后列表节点被重新渲染了那就不能一直复用最初的 UiElement 数组。比如每次点击后返回原来的approvalItems[1]已经不再是新的列表项这时候需要重新执行 Find Children。如果担心重新获取后循环会从头开始可通过记录当前项的标识比如文本内容在重新获取后先定位到该项的位置再继续。如果页面完全没有刷新只是发生了滚动或弹窗遮挡那引用一般还有效直接在新一轮循环里对剩余元素继续操作即可。判断的关键是页面有没有发生实质性的 DOM 刷新。这个在开发时可以通过观察运行日志和截图来判断。5.2 元素没在首屏Find Children 就抓不到现在很多列表页都是懒加载。第一次打开页面只有首屏 10 条数据滚到底部才会加载下一批。这种情况下你直接 Find Children拿到的一定只是首屏那几条而不是全部。处理思路很直接在获取元素之前先把页面滚动到底部触发全部加载再滚动回顶部让首屏元素可见。然后执行 Find Children。如果数据量特别大滚动一次还不够就需要循环执行“滚到底部 - 等待加载 - 再滚到底部”直到页面底部不再出现新的内容。另外滚动动作之后要加一个短延迟比如 1 到 2 秒。因为懒加载是异步的滚动之后元素还没渲染出来立刻去找就可能拿到不完整集合。宁可多等一会儿也不要为了省时间而后面对不上数。5.3 藏在 iframe 里的元素作用域选错就是空列表网页里嵌了 iframe 的情况在后台管理系统中非常常见。iframe 相当于页面里嵌套了另一个独立文档UiPath 默认的 Web 自动化作用域看不到 iframe 内部的内容。如果你发现 Find Children 返回空集合第一反应就应该是目标元素是不是在一个 iframe 里。处理办法是先用 Find Element 定位到 iframe 元素本身然后在 Find Children 里把这个 iframe 元素作为作用域容器。UiPath 支持在 iframe 内部继续查找子元素只要作用域指对了里面的元素就能正常拿到。还有一种情况是页面里有多个同类的 iframe比如多个嵌入面板。这种情况更要小心别让 UiPath 定位错 iframe。可以优先用 iframe 的 id、name 或 src 属性来限定不要只用 index。5.4 点击后新弹窗/新窗口循环上下文要切换有的详情页不是在同一标签页打开的而是新开一个标签页或弹出一个模态框。如果在循环体里直接继续点击下一个列表项流程会找不到目标元素因为当前焦点可能还在新窗口里。针对新标签页需要在点击后加一个“Attach Window”或“Switch Window”活动把上下文切换到新窗口操作完之后关闭或切回原来的列表页。针对模态框弹窗可以把它当作一个普通元素来处理用“Wait Element Appear”等待弹窗出现处理之后点关闭按钮等弹窗消失再继续循环。这里我习惯在整个循环开始之前先把列表页的窗口引用存下来。这样即使后面切换了多个窗口也能随时切回最初的列表页而不是依赖 UiPath 自动判断当前窗口。5.5 用“业务主键”而不是索引来定位剩余元素遍历点击跑了一半突然失败是很常见的事。失败后重新运行如果流程是从头开始前面已经处理过的数据会被再处理一遍造成重复操作比如重复审批、重复驳回。解决这个问题的思路我称之为“业务主键法”。在进入循环之前先把列表里每条数据的唯一标识采集出来比如单据编号、审批单号。在真正执行点击之前先判断这个标识是否已经在“已处理集合”里如果是就跳过。这样流程即使中途挂了重跑时也能从上次断掉的地方继续不会把已处理的数据再点一遍。实现上可以在循环前用 Data Scraping 抓一列单号存成一个集合变量。循环里每处理完一条就把当前单号加到另一个集合。重跑流程时加载这个集合循环内做一次包含性判断。这个方案虽然多写几步但面对生产环境时非常值得。6. 让遍历点击跑得稳的实用习惯等待、异常和日志6.1 等待活动怎么排列组合遍历点击的运行稳定性一半靠元素定位另一半靠等待策略。UiPath 里常见的等待活动有Wait Element Appear等待某个元素出现。适合在点击后确认页面加载完成时使用。Wait Element Vanish等待某个元素消失。适合等待加载动画结束、弹窗关闭等场景。Delay固定延迟。适合已知需要几秒钟的异步操作但要慎用固定延迟不是最优解能不用就不用。我的组合习惯是凡是页面跳转或刷新都用 Wait Element Appear 等待目标页面的标志元素凡是点击后出现的加载动画都用 Wait Element Vanish 等它消失只有等待时间确实无法用元素状态来判断时才用 Delay。这样可以避免流程在慢速网络环境下频繁失败。这里还要提醒一下Wait 活动的“超时时间”要设置合理。单次元素加载等 10 秒通常够了如果业务系统本身响应很慢可以放到 20 到 30 秒。超时后再执行错误处理逻辑而不是直接崩溃。6.2 Try Catch 与 Retry Scope 的配合遍历点击涉及大量循环任何一次点击异常理论上都不应该让整个流程崩溃。我会在循环体内包一层“Try Catch”把点击、操作、返回这些步骤都放在 Try 分支里Catch 分支统一记录异常信息并且把当前数据项标记为失败继续下一轮循环。如果失败原因只是网络抖动或页面加载慢那还值得重试。UiPath 里有 Retry Scope 活动可以设置重试次数和间隔。我把重试逻辑放在循环内比如同一项最多重试 3 次每次间隔 5 秒仍失败才记入失败日志。这个策略在生产环境里帮了我很多次尤其是某些业务系统在特定时段响应特别慢的时候。但重试也要考虑幂等性——如果点击后已经进入详情页并执行了操作只是返回列表时超时那重试同一个元素就可能导致重复操作。所以重试前最好先判断当前页面状态到底是“还没点进去”还是“已经操作完但返回失败”。如果已经完成了操作就不该再点而是直接跳回列表页继续下一个。6.3 循环里写日志排错效率翻倍写日志是很多人不做但关键时刻能救命的事。在遍历点击的循环里每处理一条数据都值得记录以下几类信息当前处理的是哪条元素比如单号、标题文本。点击前元素是否找到。点击后页面等待是否成功。本次循环耗时。如果出现异常把异常消息和堆栈记下来。UiPath 里可以用 Log Message 活动实现。日志级别建议用 Info 记录正常流程用 Error 记录异常。跑完一遍流程后打开输出日志只看 Error 级别就能快速定位失败在哪一条、失败原因是什么。如果没有日志一旦列表量很大你根本不知道流程跑到了哪里、在哪一步断掉的。还有一个实用小技巧在循环里的关键节点加“Take Screenshot”活动把点击前后的页面截图保存到本地。当自动化结果有争议时截图就是最直观的证据。截图命名可以带上当前元素的标识比如“101_点击前.png”“101_详情页.png”这样翻查起来一目了然。7. 收尾一点个人体会做多个遍历点击项目之后我最大的体会是这个功能写起来不难难的是让它长时间稳定运行。元素失效、懒加载、iframe、弹窗、网络波动任何一个环节出问题自动化都可能半路停工。所以如果你刚开始接触这个需求别急着把循环跑通就算完至少要在本地多测几轮尽量模拟生产环境的数据量和网络条件。另外如果页面结构很乱与其在 UiPath 里硬抠 Selector不如找前端同事协调一下让他们给列表项加一些稳定的自定义属性比如>
返回列表