简体   繁体   English

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

[英]Is there a way to get element by XPath using JavaScript in Selenium WebDriver?

I am looking for something like:我正在寻找类似的东西:

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

I need to get the innerHTML of elements using JS (to use that in Selenium WebDriver/Java, since WebDriver can't find it itself), but how?我需要使用 JS 获取元素的 innerHTML(在 Selenium WebDriver/Java 中使用它,因为 WebDriver 无法找到它本身),但是如何?

I could use ID attribute, but not all elements have ID attribute.我可以使用 ID 属性,但并非所有元素都具有 ID 属性。

[FIXED] [固定的]

I am using jsoup to get it done in Java.我正在使用 jsoup 在 Java 中完成它。 That works for my needs.这适合我的需要。

You can use document.evaluate :您可以使用document.evaluate

Evaluates an XPath expression string and returns a result of the specified type if possible.如果可能,计算 XPath 表达式字符串并返回指定类型的结果。

It is w3-standardized and whole documented: https://developer.mozilla.org/en-US/docs/Web/API/Document.evaluate它是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 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还有一个关于 mozilla 开发者网络的精彩介绍: https : //developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#document.evaluate


Alternative version, using XPathEvaluator :替代版本,使用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 Dev Tools 中,您可以运行以下命令:

$x("some xpath")

For something like $x from chrome command line api (to select multiple elements) try:对于 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;
}

This MDN overview helped: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript此 MDN 概述有帮助: https : //developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript

You can use javascript's document.evaluate to run an XPath expression on the DOM.您可以使用 javascript 的document.evaluate在 DOM 上运行 XPath 表达式。 I think it's supported in one way or another in browsers back to IE 6.我认为它在浏览器中以一种或另一种方式支持回到 IE 6。

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

IE supportsselectNodes instead. IE 支持selectNodes

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

To identify a WebElement using and you have to use the evaluate() method which evaluates an xpath expression and returns a result.要使用识别WebElement ,您必须使用评估xpath表达式并返回结果的evaluate()方法。


document.evaluate()文档.评估()

document.evaluate() returns an XPathResult based on an XPath expression and other given parameters. document.evaluate()返回一个XPathResult基于一个的XPath表达式和其它给定的参数。

The syntax is:语法是:

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

Where:在哪里:

  • xpathExpression : The string representing the XPath to be evaluated. xpathExpression :表示要评估的 XPath 的字符串。
  • contextNode : Specifies the context node for the query. contextNode :指定查询的上下文节点。 Common practice is to pass document as the context node.通常的做法是将document作为上下文节点传递。
  • namespaceResolver : The function that will be passed any namespace prefixes and should return a string representing the namespace URI associated with that prefix. namespaceResolver :将传递任何命名空间前缀的函数,并应返回一个字符串,表示与该前缀关联的命名空间 URI。 It will be used to resolve prefixes within the XPath itself, so that they can be matched with the document.它将用于解析 XPath 本身内的前缀,以便它们可以与文档匹配。 null is common for HTML documents or when no namespace prefixes are used. null常见于 HTML 文档或不使用名称空间前缀时。
  • resultType : An integer that corresponds to the type of result XPathResult to return using named constant properties , such as XPathResult.ANY_TYPE , of the XPathResult constructor, which correspond to integers from 0 to 9. resultType :一个整数,对应于使用命名常量属性返回的结果 XPathResult 的类型,例如XPathResult.ANY_TYPE ,XPathResult 构造函数,对应于从 0 到 9 的整数。
  • result : An existing XPathResult to use for the results. result :用于结果的现有 XPathResult。 null is the most common and will create a new XPathResult null是最常见的,它将创建一个新的 XPathResult

Demonstration示范

As an example the Search Box within the Google Home Page which can be identified uniquely using the xpath as //*[@name='q'] can also be identified using the Console by the following command:例如,可以使用xpath作为//*[@name='q']唯一标识的Google 主页中搜索框也可以使用控制台通过以下命令进行标识:

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

Snapshot:快照:

googlesearchbox_xpath

The same element can can also be identified using document.evaluate() and the xpath expression as follows:也可以使用document.evaluate()xpath表达式来识别相同的元素,如下所示:

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

Snapshot:快照:

document_evalute_xpath

To direct to the point , you can easily use xapth .The exact and simple way to do this using the below code .直接点,你可以很容易地使用 xapth。使用下面的代码来做到这一点的准确和简单的方法。 Kindly try and provide feedback .Thank you .请尝试并提供反馈。谢谢。

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']")));

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

Assuming your objective is to develop and test your xpath queries for screen maps.假设您的目标是开发和测试屏幕地图的 xpath 查询。 Then either use Chrome's developer tools .然后要么使用Chrome 的开发者工具 This allows you to run the xpath query to show the matches.这允许您运行 xpath 查询以显示匹配项。 Or in Firefox >9 you can do the same thing with the Web Developer Tools console .或者在 Firefox >9 中,您可以使用Web Developer Tools 控制台执行相同的操作。 In earlier version use x-path-finder or Firebug .在早期版本中使用x-path-finderFirebug

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");
    }
}

Make sure you are using the right locator for it.确保您使用的是正确的定位器。

**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

Although many browsers have $x(xPath) as a console built-in, here's an agggregation of the useful-but-hardcoded snippets from Introduction to using XPath in JavaScript ready for use in scripts:尽管许多浏览器都内置了$x(xPath)作为控制台,但这里汇总了有用但硬编码的代码片段,这些片段来自介绍到在 JavaScript 中使用 XPath准备在脚本中使用:

Snapshot快照

This gives a one-off snapshot of the xpath result set.这给出了 xpath 结果集的一次性快照。 Data may be stale after DOM mutations. 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>

First ordered node一阶节点

 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>

Iterator迭代器

Note however, that if the document is mutated (the document tree is modified) between iterations that will invalidate the iteration and the invalidIteratorState property of XPathResult is set to true , and a NS_ERROR_DOM_INVALID_STATE_ERR exception is thrown.但是请注意,如果文档在迭代之间发生变异(文档树被修改),这将使迭代无效并且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>

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Selenium WebDriver和JavaScript从XPath找到Element的文本 - Get text from XPath located Element using Selenium WebDriver with JavaScript 使用 Selenium WebDriver 和 JavaScript 从 XPath 元素获取文本 - Get text from XPath Element using Selenium WebDriver with JavaScript 通过在Selenium Webdriver的Javascript执行程序中使用Javascript XPATH获取iframe内容 - Get iframe content by using Javascript XPATH in Javascript executor for selenium webdriver How to find web element by xpath using javascript code in python selenium webdriver? - How to find web element by xpath using javascript code in python selenium webdriver? Selenium Webdriver xpath找到元素 - Selenium Webdriver xpath to find element 如何使用Jasmine JavaScript在Selenium Webdriver中获取XPath计数? - How can i get xpath count in selenium webdriver using jasmine javascript? 如何通过XPath从Selenium WebDriver中的JavaScript代码获取特定文本 - How to get a specific text from a javascript code in selenium webdriver by xpath 如何使用 JavaScript 单击 Selenium WebDriver 中的元素? - How to click an element in Selenium WebDriver using JavaScript? 有没有办法在 JavaScript 中使用其 Xpath 获取元素的文本? - Is there a way to get the Text of an element using its Xpath in JavaScript? 在 selenium webdriver 上的 javascript 中使用 xpath() 计算元素数量 - Count number of elements using xpath() in javascript on selenium webdriver
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM