Selenium遍历div子元素爬取Dojo网格用户名和角色的方法
问题说明
- 爬取场景:基于Java开发的内部网站,表格由Dojo Grid组件渲染
- 提取目标:表格内所有用户的姓名与角色字段
- 已知页面结构:每一行用户数据独立包裹在
class="dojoxGridRow"的div下的table元素中 - 现存痛点:
- 用户数据会持续新增,无法预设固定循环次数
- 现有代码使用带固定序号的绝对路径XPath,仅能获取第一行数据;核对后发现不同行的XPath仅行div的序号存在差异
- 需要实现自动遍历所有行div、自动判定遍历终点的逻辑
实现方案
核心逻辑
放弃带固定索引的绝对XPath写法,先通过特征属性批量匹配所有行元素,再逐行在当前行范围内提取目标字段,元素集合遍历完成即自动终止,无需提前获知总行数。
具体实现(以Selenium爬取场景为例)
- 批量定位所有行元素
直接通过class特征匹配所有行,XPath写法如下,不需要写行序号:
调用多元素查找接口获取当前页面所有匹配的行元素集合,哪怕后续页面动态新增用户,重新执行该查找即可拿到最新全量行数据。//div[contains(@class, 'dojoxGridRow')] - 逐行提取目标字段
遍历拿到的行元素集合,注意所有字段查找必须限定在当前行元素的范围内,避免窜行:// 拉取当前所有表格行 List<WebElement> allRows = driver.findElements(By.xpath("//div[contains(@class, 'dojoxGridRow')]")); List<UserInfo> result = new ArrayList<>(); // 集合遍历完成自动终止,无需设置固定循环次数 for (WebElement row : allRows) { // 注意XPath开头的. 代表从当前行节点向下查找,不加则会从页面根节点查找,永远返回第一行匹配结果 String name = row.findElement(By.xpath(".//td[contains(@class, 'name-field')]")).getText().trim(); String role = row.findElement(By.xpath(".//td[contains(@class, 'role-field')]")).getText().trim(); result.add(new UserInfo(name, role)); } - 动态加载场景的终点判定
如果表格是滚动加载、下拉才会渲染新行的模式,追加以下逻辑即可自动判断终点:- 每次拉取完当前可见行后,记录最后一行的唯一标识(比如最后一个用户的姓名)
- 执行滚动操作,将页面定位到当前表格最底部
- 等待1-2秒待新行渲染完成,重新拉取全量行
- 若新拉取的最后一行标识和上一次记录的完全一致,说明已经遍历到列表末尾,直接终止流程即可
常见坑点提醒
- 匹配
dojoxGridRow的class属性时必须用contains判断,不能做全值匹配:Dojo Grid会给奇偶行、选中行自动追加额外class(比如dojoxGridRowOdd、dojoxGridRowSelected),全值匹配会漏掉近一半的行 - 行内查找字段时XPath必须以
.开头,这也是之前代码只能拿到第一行数据的核心原因 - 不要使用从html根节点开始的绝对路径XPath,Dojo渲染时会动态插入DOM节点、调整节点顺序,绝对路径极易失效
内容的提问来源于stack exchange,提问作者Bats
相关产品推荐
相关产品推荐

