Как очистить текст 64076 от номера модели изделия, используя выражение xpath - PullRequest
0 голосов
/ 17 сентября 2018

Я пытаюсь очистить текст 64076 рядом с Номер модели изделия: на этой странице используя следующее выражение XPath:

//*[contains (@id,'productDetails')]//tr[contains(.,'Item model number')]/td|//*[contains (@id,'detail')]//descendant::li[contains(.,'Item model number')]/text() // I'm focusing mainly on second half of expression..

Однако, хотя это соответствует ожидаемому тексту (64076) в Firebug, он не найден при использовании Selenium WebDriver (Java).

Когда я изменяюXPath для:

//*[contains (@id,'productDetails')]//tr[contains(.,'Item model number')]/td|//*[contains (@id,'detail')]//descendant::li[contains(.,'Item model number')]

Работает, но также очищает текст Номер модели изделия: , который мне не нужен (я знаю, что могу проанализировать результат с помощью регулярных выражений, но япытаясь понять, почему мой XPath не работает, так как я четко сопоставляю фактический текст / число с помощью text(), а не жирный текст)

Спасибо

Ответы [ 6 ]

0 голосов
/ 17 сентября 2018

Попробуйте для Item model number: 64076 для теста URL

var xpathExp = 
    "//h2[.='Product details']//parent::td//div[@class='content']/ul/li/b[contains(text(),'Item')]/parent::li/text()";
var ele = $x(xpathExp);
console.dir( ele ); // Array(1)
console.log( ele[0] ); //" 64076"

Тест XML XPath online:

<ul>
  <li>
    <b>Item model number:</b> 64076
  </li>
</ul>

Дерево XMLПредставление codebeautify //ul/li/b[contains(text(),'Item')]/parent::li/text()

ul ..
li 64076 ..
b  Item model number: 

html как объекта javascript

outerHTML:"<li><b>Item model number:</b> 64076</li>"
outerText:"Item model number: 64076"

tagName:"LI"
textContent:"Item model number: 64076"

lastChild:text
    data: 64076"
    nodeValue: 64076"
    textContent: 64076"
    wholeText: 64076"
lastElementChild:b
0 голосов
/ 17 сентября 2018

В соответствии с URL-адресом, которым вы поделились, чтобы извлечь текст 64076 рядом с Номер модели изделия: на эта страница как Текст Узлу необходимо использовать WebDriverWait , чтобы требуемый элемент был видимым , и вы можете использовать следующее решение:

  • Кодовый блок:

    import org.openqa.selenium.By;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    public class q52359631_textExtract {
    
        public static void main(String[] args) {
            System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
            WebDriver driver = new FirefoxDriver();
            driver.get("https://www.amazon.com/dp/B000TW3B9G/?tag=stackoverflow17-20");
            WebElement myElement = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//td[@class='bucket']//li/b[contains(.,'Item model number:')]/..")));
            String myText = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].lastChild.textContent;", myElement);
            System.out.println(myText);
        }
    }
    
  • Консольный вывод:

     64076
    
0 голосов
/ 17 сентября 2018

Больше в @Bauban Ответ.Selenium не позволяет найти элемент с помощью текстового узла.Вы можете попробовать метод JavaScript evaluate() и оценить ваш xpath, используя JavascriptExecutor

Это ваш xpath:

//div[@class='content']//li[contains(.,'Item model number:')]/text()

И вот как вы можете оценить:

JavascriptExecutor js = (JavascriptExecutor)driver;
Object message = js.executeScript("var value = document.evaluate(\"//div[@class='content']//li[contains(.,'Item model number:')]/text()\",document, null, XPathResult.STRING_TYPE, null ); return value.stringValue;");
System.out.println(message.toString().trim());

Вы можете сослаться на эту ссылку, чтобы получить более подробную информацию о функции оценки.

0 голосов
/ 17 сентября 2018

Вы не можете использовать Selenium, чтобы получить его напрямую, потому что это TextNode. Вы можете использовать JavaScript, чтобы проверить текстовый узел и получить его.

WebElement itemModelRootNode = driver.findElement(by.xpath("//*[contains (@id,'productDetails')]//tr[contains(.,'Item model number')]/td|//*[contains (@id,'detail')]//descendant::li[contains(.,'Item model number')]");

String script = "var t = ''; arguments[0].childNodes.forEach((node)=>{ if(node.nodeType==Node.TEXT_NODE && node.textContent.trim().length > 0) { t = node.textContent.trim(); } }); return t;"

String text = ((JavascriptExecutor)driver).executeScript(script, itemModelRootNode);
0 голосов
/ 17 сентября 2018

Это распространенная проблема в селене, поскольку он поддерживает только XPath 1.0, который не включает text(). Обычный подход состоит в том, чтобы получить узел и вызвать getText().

Здесь - это красиво упакованная функция для получения текста без текста от детей:

public static String geNodeText(WebElement element) {
  String text = element.getText();
  for (WebElement child : element.findElements(By.xpath("./*"))) {
    text = text.replaceFirst(child.getText(), "");
  }
  return text;
}

Конечно, вы можете использовать строковые функции или регулярные выражения для извлечения рассматриваемой строки. Но для этого, вероятно, требуется написать собственную логику извлечения для каждого случая.

0 голосов
/ 17 сентября 2018

Это потому, что text() в XPath означает найти TextNode, но для Selenium поддержка только для поиска и возврата ElementNode. Также узел атрибутов не поддерживается Selenium, но поддерживается в XPath.

Вы должны найти родителя (который является ElementNode) TextNode, а затем использовать регулярное выражение или разделение, чтобы извлечь желаемую строчку.

String xpath = "//ul/li[b[text()='Item model number:']][contains(. , '64076')]"
driver.findElement(By.xpath(xpath)).getText().split()[1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...