有没有办法在Selenium WebDriver中使用JavaScript通过XPath获取元素?

pMa*_*Man 218 javascript xpath selenium-webdriver document.evaluate

我正在寻找类似的东西:

getElementByXpath(//html[1]/body[1]/div[1]).innerHTML
Run Code Online (Sandbox Code Playgroud)

我需要使用JS获取元素的innerHTML(在Selenium WebDriver/Java中使用它,因为WebDriver本身无法找到它),但是如何?

我可以使用ID属性,但并非所有元素都具有ID属性.

[固定]

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

yck*_*art 361

你可以使用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]") );
Run Code Online (Sandbox Code Playgroud)
<div>foo</div>
Run Code Online (Sandbox Code Playgroud)

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]") );
Run Code Online (Sandbox Code Playgroud)
<div>foo/bar</div>
Run Code Online (Sandbox Code Playgroud)

  • 幻数9是什么意思?在这里使用命名常量会更好. (11认同)
  • @WillSheppard `XPathResult.FIRST_ORDERED_NODE_TYPE === 9` https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#First_Node (5认同)
  • 我写了一个getElementByXPath函数,它支持IE,但现在支持一些基本的xpath.在那里还有一个函数getElementXpath,它们可以很好地协同工作以满足我的需要.https://gist.github.com/Joopmicroop/10471650 (2认同)

Dmi*_*yuk 144

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

$x("some xpath")
Run Code Online (Sandbox Code Playgroud)

  • 这需要更高的水平。火狐浏览器也支持它。 (7认同)
  • $x 不会在脚本中工作,它仅适用于控制台。接受的答案适用于在浏览器上下文中运行的脚本。 (2认同)

Jay*_*Jay 18

对于来自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;
}
Run Code Online (Sandbox Code Playgroud)

此MDN概述有助于:https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript


ggo*_*len 16

尽管许多浏览器都$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")]'));
Run Code Online (Sandbox Code Playgroud)
<h2>foo</h2>
<h2>foobar</h2>
<h2>bar</h2>
Run Code Online (Sandbox Code Playgroud)

第一个有序节点

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

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

迭代器

但请注意,如果文档在迭代之间发生变异(文档树被修改),则将使迭代无效,且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);
Run Code Online (Sandbox Code Playgroud)
<h2>foo</h2>
<h2>foobar</h2>
<h2>bar</h2>
Run Code Online (Sandbox Code Playgroud)


Rob*_*obG 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

  • 我想指出{document.evaluate}在IE中不起作用. (7认同)

Deb*_*anB 9

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


文档.评估()

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

语法是:

var xpathResult = document.evaluate(
  xpathExpression,
  contextNode,
  namespaceResolver,
  resultType,
  result
);
Run Code Online (Sandbox Code Playgroud)

在哪里:

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

示范

作为一个例子,搜索框的内谷歌的主页,其可唯一使用被识别的XPath//*[@name='q'],也可以使用识别出的 控制台通过以下命令:

$x("//*[@name='q']")
Run Code Online (Sandbox Code Playgroud)

快照:

googlesearchbox_xpath

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

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

快照:

document_evalute_xpath


Sam*_*lva 7

开门见山,您可以轻松地使用 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']")));
Run Code Online (Sandbox Code Playgroud)

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