Чи є спосіб отримати елемент за допомогою XPath за допомогою JavaScript у Selenium WebDriver?


252

Я шукаю щось на зразок:

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

Мені потрібно отримати внутрішнійHTML елементів за допомогою JS (щоб використовувати це у Selenium WebDriver / Java, оскільки WebDriver не може знайти його сам), але як?

Я міг би використовувати атрибут ID, але не всі елементи мають атрибут ID.

[ФІКСОВАНО]

Я використовую jsoup, щоб зробити це на Java. Це працює для моїх потреб.


2
Між іншим, htmlі bodyселектори є зайвими, оскільки 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? Тут було б краще використовувати названу константу.
Буде Шеппард

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


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

167

У Chrome Dev Tools ви можете виконати такі дії:

$x("some xpath")

1
Я пограв з цим і, здається, працює, але чи є документація на цю функцію? Я нічого не знайшов.
Ерік

Це повинно бути вище. Firefox також його підтримує.
iSWORD

Це дуже корисно при налагодженні веб-сторінки. Дякую.
theeranitp


21

Для чогось на зразок $ x з хромованого командного рядка 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

Ви можете використовувати javascript document.evaluate для запуску виразу 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.
Крістофер Бейлз

2

Припустимо, що ваша мета - розробити та протестувати ваші xpath запити на екранні карти. Тоді або скористайтеся інструментами для розробників Chrome . Це дозволяє запустити запит xpath, щоб показати збіги. Або в Firefox> 9 можна зробити те ж саме з консоллю Інструментів веб-розробників . У більш ранній версії використовуйте x-path-finder або 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
Привіт Преріт, питання полягало у виборі елемента на основі його 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


Я вважаю, що ОП не просила рішення Селена, як ваше, правда?
ankostis
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.