Apakah ada cara untuk mendapatkan elemen dengan XPath menggunakan JavaScript di Selenium WebDriver?

252

Saya mencari sesuatu seperti:

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

Saya perlu mendapatkan innerHTML elemen menggunakan JS (untuk menggunakannya di Selenium WebDriver / Java, karena WebDriver tidak dapat menemukannya sendiri), tetapi bagaimana caranya?

Saya bisa menggunakan atribut ID, tetapi tidak semua elemen memiliki atribut ID.

[TETAP]

Saya menggunakan jsoup untuk menyelesaikannya di Jawa. Itu bekerja untuk kebutuhan saya.

pMan
sumber
2
Kebetulan, htmldan bodypenyeleksi berlebihan karena DIV harus merupakan turunan dari BODY (segera atau lebih dalam) dan BODY harus merupakan anak dari HTML, jadi asalkan tidak ada elemen DIV lain dalam dokumen, //DIV[1]harus berfungsi (walaupun saya cukup cantik berkarat pada ekspresi XPath). Setara dengan DOM adalah document.getElementsByTagName('div')[1](atau mungkin 0).
RobG

Jawaban:

421

Anda bisa menggunakan document.evaluate:

Mengevaluasi string ekspresi XPath dan mengembalikan hasil dari tipe yang ditentukan jika memungkinkan.

Ini w3-standar dan seluruh didokumentasikan: 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

Ada juga pengantar yang bagus di jaringan pengembang mozilla: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#document.evaluate


Versi alternatif, menggunakan XPathEvaluator:

yaart
sumber
11
Apa arti angka ajaib 9? Akan lebih baik menggunakan konstanta bernama di sini.
Will Sheppard
5
@WillSheppard XPathResult.FIRST_ORDERED_NODE_TYPE === 9 developer.mozilla.org/en-US/docs/…
yckart
2
Saya menulis fungsi getElementByXPath yang memiliki dukungan untuk IE tetapi beberapa dukungan xpath dasar untuk saat ini. Ada juga fungsi getElementXpath di sana dan mereka bekerja dengan baik untuk apa yang saya butuhkan. gist.github.com/Joopmicroop/10471650
joopmicroop
@CiroSantilli Ya, Sir, itu adalah: w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator-evaluate
yckart
var xpathResult = document.evaluate (xpathExpression, contextNode, namespaceResolver, resultType, result);
TechDog
166

Di Alat Dev Chrome Anda dapat menjalankan yang berikut:

$x("some xpath")
Dmitry Semenyuk
sumber
1
Saya sudah bermain-main dengan ini dan sepertinya berfungsi, tetapi apakah ada dokumentasi untuk fitur ini? Saya tidak menemukan apa pun.
Eric
Ini harus lebih tinggi. Firefox juga mendukungnya.
iSWORD
Ini sangat berguna ketika Anda sedang men-debug halaman web Anda. Terima kasih.
theeranitp
21

Untuk sesuatu seperti $ x dari api baris perintah chrome (untuk memilih beberapa elemen) coba:

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

Tinjauan umum MDN ini membantu: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript

Jay
sumber
9

Anda dapat menggunakan dokumen javascript. Mengevaluasi untuk menjalankan ekspresi XPath pada DOM. Saya pikir itu didukung dalam satu atau lain cara di browser kembali ke IE 6.

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

IE mendukung SelectNodes sebagai gantinya.

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

RobG
sumber
7
Saya ingin mencatat bahwa {document.evaluate} tidak berfungsi di IE.
Christopher Bales
2

Dengan asumsi tujuan Anda adalah untuk mengembangkan dan menguji permintaan xpath Anda untuk peta layar. Kemudian gunakan alat pengembang Chrome . Ini memungkinkan Anda untuk menjalankan kueri xpath untuk menampilkan kecocokan. Atau di Firefox> 9 Anda dapat melakukan hal yang sama dengan konsol Alat Pengembang Web . Dalam versi sebelumnya gunakan x-path-finder atau Firebug .

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

Pastikan Anda menggunakan locator yang tepat untuk itu.

Prerit Jain
sumber
1
Hai Prerit, pertanyaannya adalah memilih oleh elemen berdasarkan xpath-nya. Solusi yang Anda berikan adalah memilihnya dengan id. :)
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
sumber
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
sumber
tambahkan jawaban deskriptif. deskripsi Anda akan membantu penanya untuk memahami solusi Anda dengan cepat.
NickCoder
0

Untuk mengarahkan langsung ke titik, Anda dapat dengan mudah menggunakan xapth. Cara tepat dan sederhana untuk melakukan ini menggunakan kode di bawah ini. Mohon coba dan berikan umpan balik. Terima kasih.

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

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

Sameera De Silva
sumber
Saya percaya OP tidak meminta solusi Selenium seperti milik Anda, benar?
ankostis