在Selenium WebDriver中是否有一种方法可以通过XPath使用JavaScript获取元素?

我想找的是:

getElementByXpath(//html[1]/body[1]/div[1]).innerHTML

我需要得到元素的innerHTML使用JS(使用硒WebDriver/Java,因为WebDriver不能找到它本身),但如何?

我可以使用ID属性,但不是所有元素都有ID属性。

(固定)

我使用jsoup在Java中完成它。这符合我的需要。

547656 次浏览

你可以使用javascript的document.evaluate在DOM上运行XPath表达式。我认为它在IE 6的浏览器中以某种方式得到了支持。

MDN: https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate

IE支持< em > selectNodes < / em >

MSDN: https://msdn.microsoft.com/en-us/library/ms754523 (v = vs.85) . aspx

假设您的目标是开发和测试用于屏幕映射的xpath查询。然后使用Chrome的开发工具。这允许您运行xpath查询来显示匹配。或者在Firefox >9中,你可以用Web开发人员工具控制台做同样的事情。在早期版本中使用x-path-finderFirebug

你可以使用document.evaluate:

属性的结果,并返回一个XPath表达式字符串 如果可能,指定类型

它是w3-standardized和完整的文档:https://developer.mozilla.org/en-US/docs/Web/API/Document.evaluate

function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}


console.log( getElementByXpath("//html[1]/body[1]/div[1]") );
<div>foo</div>

https://gist.github.com/yckart/6351935

There's also a great introduction on mozilla developer network: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#document.evaluate


Alternative version, using XPathEvaluator:

function getElementByXPath(xpath) {
return new XPathEvaluator()
.createExpression(xpath)
.evaluate(document, XPathResult.FIRST_ORDERED_NODE_TYPE)
.singleNodeValue
}


console.log( getElementByXPath("//html[1]/body[1]/div[1]") );
<div>foo/bar</div>

在Chrome开发工具中,您可以运行以下命令:

$x("some xpath")

对于像chrome命令行api中的$x(选择多个元素)尝试:

var xpath = function(xpathToExecute){
var result = [];
var nodesSnapshot = document.evaluate(xpathToExecute, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ ){
result.push( nodesSnapshot.snapshotItem(i) );
}
return result;
}

这个MDN概述有帮助

public class JSElementLocator {


@Test
public void locateElement() throws InterruptedException{
WebDriver driver = WebDriverProducerFactory.getWebDriver("firefox");


driver.get("https://www.google.co.in/");




WebElement searchbox = null;


Thread.sleep(1000);
searchbox = (WebElement) (((JavascriptExecutor) driver).executeScript("return document.getElementById('lst-ib');", searchbox));
searchbox.sendKeys("hello");
}
}

确保您使用了正确的定位器。

**Different way to Find Element:**


IEDriver.findElement(By.id("id"));
IEDriver.findElement(By.linkText("linkText"));
IEDriver.findElement(By.xpath("xpath"));


IEDriver.findElement(By.xpath(".//*[@id='id']"));
IEDriver.findElement(By.xpath("//button[contains(.,'button name')]"));
IEDriver.findElement(By.xpath("//a[contains(.,'text name')]"));
IEDriver.findElement(By.xpath("//label[contains(.,'label name')]"));


IEDriver.findElement(By.xpath("//*[contains(text(), 'your text')]");


Check Case Sensitive:
IEDriver.findElement(By.xpath("//*[contains(lower-case(text()),'your text')]");


For exact match:
IEDriver.findElement(By.xpath("//button[text()='your text']");


**Find NG-Element:**


Xpath == //td[contains(@ng-show,'childsegment.AddLocation')]
CssSelector == .sprite.icon-cancel
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;


System.setProperty("webdriver.chrome.driver", "path of your chrome exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com");


driver.findElement(By.xpath(".//*[@id='UserName']")).clear();
driver.findElement(By.xpath(".//*[@id='UserName']")).sendKeys(Email);

为了直奔主题,您可以轻松地使用xapth。使用下面的代码来实现这一点的准确而简单的方法。请尝试提供反馈。谢谢。

JavascriptExecutor js = (JavascriptExecutor) driver;


//To click an element
WebElement element=driver.findElement(By.xpath(Xpath));
js.executeScript(("arguments[0].click();", element);


//To gettext


String theTextIWant = (String) js.executeScript("return arguments[0].value;",driver.findElement(By.xpath("//input[@id='display-name']")));

进一步读数- https://medium.com/@smeesheady/webdriver-javascriptexecutor-interact-with-elements-and-open-and-handle-multiple-tabs-and-get-url-dcfda49bfa0f < / p >

要使用识别WebElement,必须使用evaluate()方法,该方法计算xpath表达式并返回结果。


document.evaluate ()

document.evaluate ()返回基于XPath表达式和其他给定参数的XPathResult

语法为:

var xpathResult = document.evaluate(
xpathExpression,
contextNode,
namespaceResolver,
resultType,
result
);

地点:

  • xpathExpression:表示要计算的XPath的字符串。
  • contextNode:指定查询的上下文节点。通常的做法是传递document作为上下文节点。
  • namespaceResolver:将传递任何命名空间前缀的函数,并应返回表示与该前缀关联的命名空间URI的字符串。它将用于解析XPath本身中的前缀,以便它们能够与文档匹配。null通常用于HTML文档或不使用名称空间前缀的情况。
  • resultType:一个整数,对应于XPathResult返回的结果类型,使用XPathResult构造函数的命名常量属性,例如XPathResult.ANY_TYPE,它对应于0到9的整数。
  • result:一个现有的用于结果的XPathResult。null是最常见的,它将创建一个新的XPathResult

示范

例如,谷歌首页中的搜索框可以用xpath作为//*[@name='q']唯一标识,也可以用 控制台通过以下命令标识:

$x("//*[@name='q']")

快照:

googlesearchbox_xpath

同样的元素也可以用document.evaluate()xpath表达式来标识,如下所示:

document.evaluate("//*[@name='q']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

快照:

document_evalute_xpath

虽然许多浏览器都内置了$x(xPath)作为控制台,但这里有一个来自在JavaScript中使用XPath的介绍的有用但硬编码的片段聚合,可以在脚本中使用:

快照

这给出了xpath结果集的一次性快照。DOM突变后,数据可能会过时。

const $x = xp => {
const snapshot = document.evaluate(
xp, document, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null
);
return [...Array(snapshot.snapshotLength)]
.map((_, i) => snapshot.snapshotItem(i))
;
};


console.log($x('//h2[contains(., "foo")]'));
<h2>foo</h2>
<h2>foobar</h2>
<h2>bar</h2>

一阶节点

const $xOne = xp =>
document.evaluate(
xp, document, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null
).singleNodeValue
;


console.log($xOne('//h2[contains(., "foo")]'));
<h2>foo</h2>
<h2>foobar</h2>
<h2>bar</h2>

迭代器

但是请注意,如果文档在迭代之间发生了突变(文档树被修改),将使迭代无效,并且XPathResultinvalidIteratorState属性被设置为true,并且抛出NS_ERROR_DOM_INVALID_STATE_ERR异常。

function *$xIter(xp) {
const iter = document.evaluate(
xp, document, null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE, null
);


for (;;) {
const node = iter.iterateNext();
    

if (!node) {
break;
}
    

yield node;
}
}


// dump to array
console.log([...$xIter('//h2[contains(., "foo")]')]);


// return next item from generator
const xpGen = $xIter('//h2[text()="foo"]');
console.log(xpGen.next().value);
<h2>foo</h2>
<h2>foobar</h2>
<h2>bar</h2>