使用 Selenium WebDriver,我可以获得页面中所有 Web 元素的列表。我想编写一个函数,它将返回传递元素的 XPath 字符串。
调用函数将类似于:-
String XpathOfElement = myWebDriver.getXpath(My_Web_Element)
提示:-我认为我们可以使用javascript(使用JavaScriptExecuter)。但对javascript不熟悉。
检查这个post,我编写了代码来获取绝对XPath。
public static String getAbsoluteXPath(WebElement element)
{
return (String) ((JavascriptExecutor) driver).executeScript(
"function absoluteXPath(element) {"+
"var comp, comps = [];"+
"var parent = null;"+
"var xpath = '';"+
"var getPos = function(element) {"+
"var position = 1, curNode;"+
"if (element.nodeType == Node.ATTRIBUTE_NODE) {"+
"return null;"+
"}"+
"for (curNode = element.previousSibling; curNode; curNode = curNode.previousSibling) {"+
"if (curNode.nodeName == element.nodeName) {"+
"++position;"+
"}"+
"}"+
"return position;"+
"};"+
"if (element instanceof Document) {"+
"return '/';"+
"}"+
"for (; element && !(element instanceof Document); element = element.nodeType == Node.ATTRIBUTE_NODE ? element.ownerElement : element.parentNode) {"+
"comp = comps[comps.length] = {};"+
"switch (element.nodeType) {"+
"case Node.TEXT_NODE:"+
"comp.name = 'text()';"+
"break;"+
"case Node.ATTRIBUTE_NODE:"+
"comp.name = '@' + element.nodeName;"+
"break;"+
"case Node.PROCESSING_INSTRUCTION_NODE:"+
"comp.name = 'processing-instruction()';"+
"break;"+
"case Node.COMMENT_NODE:"+
"comp.name = 'comment()';"+
"break;"+
"case Node.ELEMENT_NODE:"+
"comp.name = element.nodeName;"+
"break;"+
"}"+
"comp.position = getPos(element);"+
"}"+
"for (var i = comps.length - 1; i >= 0; i--) {"+
"comp = comps[i];"+
"xpath += '/' + comp.name.toLowerCase();"+
"if (comp.position !== null) {"+
"xpath += '[' + comp.position + ']';"+
"}"+
"}"+
"return xpath;"+
"} return absoluteXPath(arguments[0]);", element);
}
这段代码完美运行。
public String getXpath(WebElement ele) {
String str = ele.toString();
String[] listString;
if(str.contains("xpath")
listString = str.split("xpath:");
else if(str.contains("id")
listString = str.split("id:");
String last = listString[1].trim();
return last.substring(0, last.length() - 1);
}
上述函数仅在 WebElement 具有 xpath 时才有效。假设你的元素有 class,然后使用 if-else 概念和“class:”作为分割表达式。
WebElement element1 = driver.findElement(By.xpath("//*[@id=\"APjFqb\"]"));
String xpath1 = element1.toString();
String[] data1 = xpath1.split(" -> xpath: ",2);
String final_xpath = data1[1].replace("\"]]]", "\"]");
System.out.println(final_xpath);
DOM 中的几乎任何元素都可以有很多有效的 xPath。例如,Google 搜索页面上的输入字段可以为:
//*[@id='lst-ib']
//*[@class='gsfi'][1]
//body//div//input[3]
...
您期望得到哪一件?
其实google在chrome里就有这个算法。我们可以复制元素的 xpath,但在大多数情况下这很糟糕。 所以这是可以做到的,如果这对你来说真的很重要,看看 NHtmlUnit - 你可以获取页面的 dom,在那里找到你的元素,然后转到根元素,向路径字符串添加标签。我想,有可能得到类似
//body/div/div[2]/div[3]/...
但为什么呢?