Java Selenium如何通过类名获取动态XPath网页元素的对应XPath
解决方案
方案1:优化定位逻辑,无需依赖动态XPath(推荐)
你完全不需要获取动态变化的XPath,基于固定类名构造稳定定位方式即可,改动成本极低:
- 先基于固定类名构造稳定的表格XPath,只要类名不变这个XPath就不会失效,示例如下(替换为你实际的表格类名即可):
String table_xpath = "//table[contains(@class, '你的固定表格类名')]"; - 原有子元素查找逻辑可以简化,不需要拼接父元素XPath:已经拿到
Webtable实例后,用.开头的相对XPath就可以直接查找当前元素下的子节点,不需要知道父元素的完整XPath。
修改后的可运行代码如下:
// 替换为你实际的表格固定类名 String table_xpath = "//table[contains(@class, '你的固定表格类名')]"; wait_page_loading(By.xpath(table_xpath)); WebElement Webtable = driver.findElement(By.xpath(table_xpath)); // 直接用相对路径查找当前表格下的行,不需要拼接table_xpath List<WebElement> totalRowCount = Webtable.findElements(By.xpath("./tbody/tr")); if(totalRowCount.size() <= 1) { throw new Exception("Can't find results in the problem page"); } // 同样用相对路径找单元格 return totalRowCount.get(0).findElements(By.xpath("./td")).get(6).getText();
方案2:如果确实需要获取已找到元素的对应XPath
如果你的后续逻辑必须要用到表格元素的完整XPath字符串,可以通过执行JavaScript的方式从已定位到的元素中提取,工具方法示例如下:
public String getElementXPath(WebDriver driver, WebElement element) { JavascriptExecutor js = (JavascriptExecutor) driver; return (String) js.executeScript( "function getXPath(elem){" + "if(elem.id!=='') return '//*[@id=\"'+elem.id+'\"]';" + "if(elem===document.body) return '/'+elem.tagName.toLowerCase();" + "var count=0, siblings=elem.parentNode.childNodes;" + "for(var i=0;i<siblings.length;i++){" + "var sibling=siblings[i];" + "if(sibling===elem) return getXPath(elem.parentNode)+'/'+elem.tagName.toLowerCase()+'['+(count+1)+']';" + "if(sibling.nodeType===1 && sibling.tagName.toLowerCase()===elem.tagName.toLowerCase()) count++;" + "}" + "}" + "return getXPath(arguments[0]);", element); }
调用方式:先通过类名定位到表格元素,再调用上面的方法获取它的XPath即可。
注意:方案1的稳定性远高于方案2,动态生成的绝对XPath很容易因为页面结构的微小调整失效,优先使用方案1。
内容的提问来源于stack exchange,提问作者Blue Fire
相关产品推荐
相关产品推荐

