Selenium读取表格IMO编号列仅返回首行无法遍历所有行问题
问题根因排查
- 变量名不一致:代码首行定义的存储IMO元素列表的变量名为
no,后续获取列表长度、遍历取值时使用的变量名为imono,如果实际运行代码确实存在该笔误,会直接导致空指针或取值异常,即使为粘贴时的输入错误,也需优先确认变量名统一。 - 元素捕获时机错误:在调用
VesselPositionsUtil.FetchIMOnumber(driver)方法前就完成了IMO元素列表的捕获,若该工具方法执行过程中触发了页面刷新、DOM重绘,提前捕获的元素列表会变为过时元素(Stale Element),遍历到第二个元素时会抛出异常终止,自然仅能打印第一行内容。 - 不可见元素取值失败:如果表格存在滚动条,第二行及以后的IMO元素不在当前可视区域内,部分版本的驱动会出现
getText()取不到值甚至抛出异常的问题,导致循环终止。 - 单选按钮定位逻辑错误:当前匹配单选按钮的XPath使用了
following轴,会匹配第二个表格之后所有的单选按钮,无法精准对应当前遍历行,后续即使匹配到IMO编号也容易点错按钮。
修复后的代码示例
// 先从其他页面获取目标IMO编号,避免后续操作触发DOM更新导致元素失效 String targetImo = VesselPositionsUtil.FetchIMOnumber(driver); // 显式等待所有IMO编号元素加载完成,再捕获元素列表 WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); List<WebElement> imoList = wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy( By.xpath("//table//tr//td[contains(@class,'mat-column-imoNumber')]/span") )); // 遍历所有IMO元素 for (int i = 0; i < imoList.size(); i++) { WebElement imoEle = imoList.get(i); // 用getAttribute("textContent")代替getText(),避免不可见元素取不到值的问题 String currentImo = imoEle.getAttribute("textContent").trim(); System.out.println("Get the text:" + currentImo); if (currentImo.equals(targetImo)) { // 从当前IMO元素向上找到对应的行节点,再定位该行的单选按钮,精准匹配 WebElement radioBtn = imoEle.findElement(By.xpath("./ancestor::tr//mat-radio-button")); // 点击前先滚动到元素可见位置 ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoViewIfNeeded(true);", radioBtn); radioBtn.click(); break; } }
优化说明
- 调整元素获取顺序,先拿到目标IMO编号再查询页面元素,避免中间页面跳转/刷新导致提前捕获的元素过期失效
- 使用
visibilityOfAllElementsLocatedBy显式等待,确保所有行的IMO元素都渲染完成后再开始遍历,不会出现列表长度不足的问题 - 用
getAttribute("textContent")代替getText(),即使元素不在可视区域也能正常获取文本内容 - 采用相对路径定位单选按钮,从当前IMO元素向上找父行,再匹配该行内的单选按钮,不会点错其他行的按钮
- 增加滚动到元素可见的逻辑,避免元素被遮挡导致点击失败
内容的提问来源于stack exchange,提问作者jay m
相关产品推荐
相关产品推荐

