Gibt es eine Möglichkeit, ein Element von XPath mithilfe von JavaScript in Selenium WebDriver abzurufen?


252

Ich suche so etwas wie:

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

Ich muss das innerHTML von Elementen mit JS abrufen (um das in Selenium WebDriver / Java zu verwenden, da WebDriver es selbst nicht finden kann), aber wie?

Ich könnte das ID-Attribut verwenden, aber nicht alle Elemente haben das ID-Attribut.

[FEST]

Ich benutze jsoup, um es in Java zu erledigen. Das funktioniert für meine Bedürfnisse.


2
Im Übrigen sind die Selektoren htmlund bodyüberflüssig, da ein DIV ein Nachkomme von BODY sein muss (unmittelbar oder tiefer) und BODY ein Kind von HTML sein muss. Vorausgesetzt, es gibt keine anderen DIV-Elemente im Dokument, //DIV[1]sollte dies funktionieren (obwohl ich hübsch bin rostig auf XPath-Ausdrücken). Das DOM-Äquivalent ist document.getElementsByTagName('div')[1](oder vielleicht 0).
RobG

Antworten:


421

Sie können verwenden document.evaluate:

Wertet eine XPath-Ausdruckszeichenfolge aus und gibt nach Möglichkeit ein Ergebnis des angegebenen Typs zurück.

Es ist w3-standardisiert und vollständig dokumentiert: 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

Es gibt auch eine großartige Einführung in das Mozilla-Entwicklernetzwerk: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#document.evaluate


Alternative Version mit XPathEvaluator:


11
Was bedeutet die magische Zahl 9? Es wäre besser, hier eine benannte Konstante zu verwenden.
Will Sheppard

5
@ WillSheppard XPathResult.FIRST_ORDERED_NODE_TYPE === 9 developer.mozilla.org/en-US/docs/…
yckart

2
Ich habe eine getElementByXPath-Funktion geschrieben, die IE unterstützt, aber vorerst einige grundlegende xpath-Unterstützung bietet. Es gibt auch eine Funktion getElementXpath und sie arbeiten gut zusammen für das, was ich brauchte. gist.github.com/Joopmicroop/10471650
Joopmicroop


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


21

Für etwas wie $ x von der Chrome-Befehlszeilen-API (um mehrere Elemente auszuwählen) versuchen Sie:

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

Diese MDN-Übersicht hat geholfen: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript


9

Sie können das document.evaluate von Javascript verwenden , um einen XPath-Ausdruck im DOM auszuführen. Ich denke, es wird auf die eine oder andere Weise in Browsern zurück zu IE 6 unterstützt.

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

IE unterstützt stattdessen selectNodes .

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


7
Ich möchte darauf hinweisen, dass {document.evaluate} im IE nicht funktioniert.
Christopher Bales


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

Stellen Sie sicher, dass Sie den richtigen Locator dafür verwenden.


1
Hallo Prerit, die Frage war, durch ein Element basierend auf seinem xpath auszuwählen. Die von Ihnen bereitgestellte Lösung besteht darin, sie anhand der ID auszuwählen. :)
Gaurav Thantry

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

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

Fügen Sie eine beschreibende Antwort hinzu. Ihre Beschreibung hilft dem Fragesteller, Ihre Lösung schnell zu verstehen.
NickCoder

0

Um auf den Punkt zu gelangen, können Sie einfach xapth verwenden. Die genaue und einfache Möglichkeit, dies mit dem folgenden Code zu tun. Bitte versuchen Sie, Feedback zu geben. Vielen Dank.

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

Weitere Lesungen - https://medium.com/@smeesheady/webdriver-javascriptexecutor-interact-with-elements-and-open-and-handle-multiple-tabs-and-get-url-dcfda49bfa0f


Ich glaube, das OP hat nicht nach einer Selenlösung wie Ihrer gefragt, richtig?
Ankostis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.