มีวิธีรับองค์ประกอบโดย XPath โดยใช้ JavaScript ใน Selenium WebDriver หรือไม่


252

ฉันกำลังมองหาบางสิ่งที่ชอบ:

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

ฉันต้องการรับองค์ประกอบ HTML ภายในโดยใช้ JS (เพื่อใช้ใน Selenium WebDriver / Java เนื่องจาก WebDriver ไม่สามารถค้นหาได้เอง) แต่ทำได้อย่างไร

ฉันสามารถใช้แอตทริบิวต์ ID แต่องค์ประกอบบางอย่างไม่มีแอตทริบิวต์ ID

[แก้ไขแล้ว]

ฉันใช้ jsoup เพื่อให้เสร็จใน Java ที่เหมาะกับความต้องการของฉัน


2
อนึ่ง the htmlและbodyselectors นั้นฟุ่มเฟือยเนื่องจาก DIV จะต้องสืบทอดมาจาก BODY (ทันทีหรือลึกกว่า) และ BODY ต้องเป็นลูกของ HTML ดังนั้นหากไม่มีองค์ประกอบ DIV อื่นในเอกสาร//DIV[1]ควรทำงานได้ (แม้ว่าฉันจะสวย เป็นสนิมบนนิพจน์ XPath) ค่าเทียบเท่า DOM คือdocument.getElementsByTagName('div')[1](หรืออาจจะ0)
RobG

คำตอบ:


422

คุณสามารถใช้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:


11
เลข 9 หมายถึงอะไร? มันจะเป็นการดีกว่าถ้าคุณใช้ค่าคงที่ที่มีชื่อที่นี่
จะ Sheppard Will

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

2
ฉันได้เขียนฟังก์ชั่น getElementByXPath ที่มีการรองรับ IE แต่มีการสนับสนุน xpath พื้นฐานสำหรับตอนนี้ นอกจากนี้ยังมีฟังก์ชั่น getElementXpath ในนั้นและพวกเขาทำงานร่วมกันอย่างดีสำหรับสิ่งที่ฉันต้องการ gist.github.com/Joopmicroop/10471650
joopmicroop

@CiroSantilli ใช่แล้วมันคือ: w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator-evaluate
yckart

var xpathResult = document.evaluate (xpathExpression, contextNode, namespaceResolver, resultType, ผลลัพธ์);
TechDog

167

ใน Chrome Dev Tools คุณสามารถเรียกใช้สิ่งต่อไปนี้:

$x("some xpath")

1
ฉันเคยลองดูแล้วดูเหมือนว่ามันจะใช้งานได้ แต่มีเอกสารอะไรบ้างสำหรับคุณสมบัตินี้? ฉันไม่พบอะไรเลย
Eric

สิ่งนี้จะต้องสูงขึ้นไป Firefox ก็รองรับเช่นกัน
iSWORD

สิ่งนี้มีประโยชน์มากเมื่อคุณทำการดีบักเว็บเพจของคุณ ขอบคุณ
theeranitp


21

สำหรับบางอย่างเช่น $ x จาก chrome command line api (เพื่อเลือกหลายองค์ประกอบ) ลอง:

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


9

คุณสามารถใช้เอกสารของจาวาสคริปต์ประเมินค่าเพื่อเรียกใช้นิพจน์ XPath บน DOM ฉันคิดว่ามันรองรับไม่ทางใดก็ทางหนึ่งในเบราว์เซอร์กลับไปที่ 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


7
ฉันต้องการทราบว่า {document.evaluate} ไม่ทำงานใน IE
Christopher Bales

2

สมมติว่าวัตถุประสงค์ของคุณคือการพัฒนาและทดสอบ xpath ของคุณสำหรับแผนที่หน้าจอ แล้วทั้งใช้เครื่องมือสำหรับนักพัฒนาของ Chrome สิ่งนี้ช่วยให้คุณเรียกใช้แบบสอบถาม xpath เพื่อแสดงรายการที่ตรงกัน หรือใน Firefox> 9 คุณสามารถทำสิ่งเดียวกันกับเครื่องมือพัฒนาเว็บคอนโซล ก่อนหน้านี้ในการใช้งานรุ่นX-เส้นทางค้นหาหรือFirebug


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

ตรวจสอบให้แน่ใจว่าคุณใช้ตัวระบุตำแหน่งที่ถูกต้อง


1
สวัสดี Prerit คำถามคือการเลือกโดยองค์ประกอบตาม xpath ของมัน วิธีแก้ปัญหาที่คุณให้ไว้คือเลือกโดยใช้รหัส :)
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);

เพิ่มคำตอบที่เป็นคำอธิบาย คำอธิบายของคุณจะช่วยให้ผู้ถามเพื่อให้เข้าใจถึงวิธีแก้ปัญหาของคุณ
NickCoder

0

เพื่อตรงไปยังจุดที่คุณสามารถใช้ 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


ฉันเชื่อว่า OP ไม่ได้ขอซีลีเนียมอย่างเช่นคุณใช่ไหม?
ankostis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.