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.

pMan
quelle
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:

yckart
quelle
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
166

In Chrome Dev Tools können Sie Folgendes ausführen:

$x("some xpath")
Dmitry Semenyuk
quelle
1
Ich habe damit herumgespielt und es scheint zu funktionieren, aber gibt es eine Dokumentation für diese Funktion? Ich habe nichts gefunden
Eric
Dies muss höher sein. Firefox unterstützt es auch.
iSWORD
Dies ist sehr nützlich, wenn Sie Ihre Webseite debuggen. Vielen Dank.
Theeranitp
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

Jay
quelle
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

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

Angenommen, Ihr Ziel ist es, Ihre xpath-Abfragen für Bildschirmkarten zu entwickeln und zu testen. Verwenden Sie dann entweder die Entwicklertools von Chrome . Auf diese Weise können Sie die xpath-Abfrage ausführen, um die Übereinstimmungen anzuzeigen. In Firefox> 9 können Sie dasselbe mit der Web Developer Tools-Konsole tun . In früheren Versionen verwenden x-path-finder oder Firebug .

Martin Spamer
quelle
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.

Prerit Jain
quelle
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
Alok Patel
quelle
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);
Dharit Mehta
quelle
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

Sameera De Silva
quelle
Ich glaube, das OP hat nicht nach einer Selenlösung wie Ihrer gefragt, richtig?
Ankostis