我正在寻找类似的东西:
getElementByXpath(//html[1]/body[1]/div[1]).innerHTML
我需要使用JS获取元素的innerHTML(在Selenium WebDriver / Java中使用它,因为WebDriver本身找不到它),但是如何?
我可以使用ID属性,但并非所有元素都具有ID属性。
[固定]
我正在使用jsoup在Java中完成它。这符合我的需要。
答案 0 :(得分:328)
您可以使用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
还有一个关于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</div>
答案 1 :(得分:127)
在Chrome开发者工具中,您可以运行以下命令:
$x("some xpath")
答案 2 :(得分:15)
对于来自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
答案 3 :(得分:9)
您可以使用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
答案 4 :(得分:2)
假设您的目标是开发和测试屏幕映射的xpath查询。然后使用Chrome's developer tools。这允许您运行xpath查询以显示匹配项。或者在Firefox&gt; 9中,您可以使用Web Developer Tools console执行相同的操作。在早期版本中,请使用x-path-finder或Firebug。
答案 5 :(得分:2)
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");
}
}
确保使用正确的定位器。
答案 6 :(得分:2)
要使用WebElement和xpath来标识javascript,您必须使用evaluate()
方法,该方法对 xpath 表达式求值并返回结果
document.evaluate()返回基于XPathResult表达式和其他给定参数的XPath。
语法是:
var xpathResult = document.evaluate(
xpathExpression,
contextNode,
namespaceResolver,
resultType,
result
);
位置:
xpathExpression
:代表要评估的XPath的字符串。contextNode
:指定查询的上下文节点。通常的做法是将document
作为上下文节点。namespaceResolver
:该函数将传递任何名称空间前缀,并应返回一个字符串,该字符串表示与该前缀关联的名称空间URI。它将用于解析XPath本身中的前缀,以便它们可以与文档匹配。 null
对于HTML文档或不使用名称空间前缀的情况很常见。resultType
:一个整数,它对应于要使用XPathResult构造函数的named constant properties返回的结果XPathResult的类型,例如XPathResult.ANY_TYPE
,它对应于0到9之间的整数。 result
:现有的XPathResult用于结果。 null
是最常见的,它将创建一个新的XPathResult 例如,Google Home Page中的 Search Box 可以使用 xpath 唯一地标识为//*[@name='q']
,也可以使用通过以下命令google-chrome-devtools 控制台:
$x("//*[@name='q']")
快照:
还可以使用document.evaluate()
和 xpath 表达式来标识相同的元素,如下所示:
document.evaluate("//*[@name='q']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
快照:
答案 7 :(得分:0)
**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
答案 8 :(得分:0)
const serviceAccount = require("./serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
storageBucket: "<YOUR APP ID>.appspot.com",
databaseURL: "https://<YOUR APP ID>.firebaseio.com"
});
答案 9 :(得分:0)
要指向重点,您可以轻松地使用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']")));
答案 10 :(得分:0)
尽管许多浏览器都将 $x(xPath)
作为内置控制台,但这里汇总了来自 Introduction to using XPath in JavaScript 的有用但硬编码的片段,可用于脚本:
这给出了 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>