Czy istnieje sposób na uzyskanie elementu przez XPath przy użyciu JavaScript w Selenium WebDriver?


252

Szukam czegoś takiego:

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

Potrzebuję uzyskać innerHTML elementów za pomocą JS (aby użyć go w Selenium WebDriver / Java, ponieważ WebDriver nie może go znaleźć), ale jak?

Mógłbym użyć atrybutu ID, ale nie wszystkie elementy mają atrybut ID.

[NAPRAWIONY]

Używam jsoup, aby zrobić to w Javie. To działa na moje potrzeby.


2
Nawiasem mówiąc, selektory htmli bodysą zbędne, ponieważ DIV musi być potomkiem BODY (natychmiastowego lub głębszego), a BODY musi być dzieckiem HTML, więc pod warunkiem, że nie ma innych elementów DIV w dokumencie, //DIV[1]powinien działać (chociaż jestem ładna zardzewiały na wyrażeniach XPath). Odpowiednikiem DOM jest document.getElementsByTagName('div')[1](a może 0).
RobG

Odpowiedzi:


422

Możesz użyć document.evaluate:

Oblicza ciąg wyrażenia XPath i, jeśli to możliwe, zwraca wynik określonego typu.

Jest standaryzowany w3 i w pełni udokumentowany: 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

Jest także świetne wprowadzenie do sieci deweloperów Mozilli: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#document.evaluate


Alternatywna wersja, wykorzystująca XPathEvaluator:


11
Co oznacza magiczna liczba 9? Lepiej byłoby użyć tutaj nazwanej stałej.
Will Sheppard,

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

2
Napisałem funkcję getElementByXPath, która obsługuje IE, ale na razie podstawową obsługę xpath. Jest tam również funkcja getElementXpath i działają one ładnie razem dla tego, czego potrzebowałem. gist.github.com/Joopmicroop/10471650
joopmicroop

@CiroSantilli Tak, proszę pana, to jest: w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator-evaluate
yckart

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


21

Aby uzyskać coś takiego jak $ x z interfejsu wiersza polecenia chrome (aby wybrać wiele elementów), spróbuj:

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

Omówienie MDN pomogło: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript




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

Upewnij się, że używasz do tego odpowiedniego lokalizatora.


1
Cześć Prerit, pytanie polegało na wybraniu elementu na podstawie jego ścieżki x. Podane rozwiązanie polega na wybraniu go według identyfikatora. :)
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);

dodaj opisową odpowiedź. Twój opis pomoże pytającemu szybko zrozumieć twoje rozwiązanie.
NickCoder,

0

Aby przejść do rzeczy, możesz łatwo użyć xapth. Dokładny i prosty sposób na zrobienie tego za pomocą poniższego kodu. Prosimy postarać się o opinie. Dziękuję.

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

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


Uważam, że OP nie poprosił o rozwiązanie Selenium takie jak twoje, prawda?
ankostis
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.