簡體   English   中英

有沒有辦法在 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 屬性。

[固定的]

我正在使用 jsoup 在 Java 中完成它。 這適合我的需要。

您可以使用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>

在 Chrome Dev Tools 中,您可以運行以下命令:

$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 概述有幫助: https : //developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript

您可以使用 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

要使用識別WebElement ,您必須使用評估xpath表達式並返回結果的evaluate()方法。


文檔.評估()

document.evaluate()返回一個XPathResult基於一個的XPath表達式和其它給定的參數。

語法是:

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

在哪里:

  • xpathExpression :表示要評估的 XPath 的字符串。
  • contextNode :指定查詢的上下文節點。 通常的做法是將document作為上下文節點傳遞。
  • namespaceResolver :將傳遞任何命名空間前綴的函數,並應返回一個字符串,表示與該前綴關聯的命名空間 URI。 它將用於解析 XPath 本身內的前綴,以便它們可以與文檔匹配。 null常見於 HTML 文檔或不使用名稱空間前綴時。
  • resultType :一個整數,對應於使用命名常量屬性返回的結果 XPathResult 的類型,例如XPathResult.ANY_TYPE ,XPathResult 構造函數,對應於從 0 到 9 的整數。
  • result :用於結果的現有 XPathResult。 null是最常見的,它將創建一個新的 XPathResult

示范

例如,可以使用xpath作為//*[@name='q']唯一標識的Google 主頁中搜索框也可以使用控制台通過以下命令進行標識:

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

快照:

googlesearchbox_xpath

也可以使用document.evaluate()xpath表達式來識別相同的元素,如下所示:

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

快照:

document_evalute_xpath

直接點,你可以很容易地使用 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

假設您的目標是開發和測試屏幕地圖的 xpath 查詢。 然后要么使用Chrome 的開發者工具 這允許您運行 xpath 查詢以顯示匹配項。 或者在 Firefox >9 中,您可以使用Web Developer Tools 控制台執行相同的操作。 在早期版本中使用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");
    }
}

確保您使用的是正確的定位器。

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

盡管許多瀏覽器都內置了$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>

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM