提问人:pMan 提问时间:5/15/2012 最后编辑:ggorlenpMan 更新时间:10/11/2023 访问量:631482
有没有办法在 Selenium WebDriver 中使用 JavaScript 通过 XPath 获取元素?
Is there a way to get element by XPath using JavaScript in Selenium WebDriver?
问:
我正在寻找类似的东西:
getElementByXpath(//html[1]/body[1]/div[1]).innerHTML
我需要使用 JS 获取元素的 innerHTML(在 Selenium WebDriver/Java 中使用它,因为 WebDriver 本身找不到它),但如何?
我可以使用 ID 属性,但并非所有元素都有 ID 属性。
答:
您可以使用 javascript 的 document.evaluate 在 DOM 上运行 XPath 表达式。我认为它在 IE 6 的浏览器中以一种或另一种方式得到支持。
MDN:https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate
IE 支持 selectNodes。
MSDN:https://msdn.microsoft.com/en-us/library/ms754523(v=vs.85).aspx
评论
假设您的目标是开发和测试屏幕映射的 xpath 查询。然后,要么使用 Chrome 的开发者工具。这允许您运行 xpath 查询以显示匹配项。或者在 Firefox >9 中,您可以使用 Web 开发人员工具控制台执行相同的操作。在早期版本中,请使用 x-path-finder 或 Firebug。
您可以使用:document.evaluate
计算 XPath 表达式字符串并返回 如果可能,请指定类型。
它是 w3 标准化的,并完整地记录了: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
Mozilla开发者网络上也有一个很好的介绍:https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#document.evaluate
替代版本,使用: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>
评论
XPathResult.FIRST_ORDERED_NODE_TYPE === 9
在 Chrome 开发工具中,您可以运行以下命令:
$x("some xpath")
评论
$x("")
对于类似 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 概述有帮助: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript
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']")));
评论
要使用 xpath 和 javascript 标识 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 本身中的前缀,以便它们可以与文档匹配。 对于 HTML 文档或未使用命名空间前缀时很常见。null
resultType
:一个整数,对应于使用命名常量属性(如 XPathResult 构造函数的 )返回的结果类型 XPathResult,该属性对应于 0 到 9 之间的整数。XPathResult.ANY_TYPE
result
:用于结果的现有 XPathResult。 是最常见的,将创建新的 XPathResultnull
示范
例如,Google 主页中的搜索框可以使用 xpath 进行唯一标识,也可以使用 google-chrome-devtools 控制台通过以下命令进行标识://*[@name='q']
$x("//*[@name='q']")
快照:
也可以使用 和 xpath 表达式来标识相同的元素,如下所示:document.evaluate()
document.evaluate("//*[@name='q']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
快照:
尽管许多浏览器都内置了控制台,但这里汇总了在 JavaScript 中使用 XPath 简介中有用但硬编码的片段,这些片段可在脚本中使用:$x(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>
迭 代
但请注意,如果文档在迭代之间发生变异(修改文档树),这将使迭代无效,并且属性设置为 ,并且会引发异常。
invalidIteratorState
XPathResult
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>
评论
html
body
//DIV[1]
document.getElementsByTagName('div')[1]
0