如何使用XPath表达式从Item型号中抓取文本64076

时间:2018-09-17 01:06:37

标签: java selenium selenium-webdriver xpath webdriverwait

我正在尝试在{{3上的“ 项目型号: 旁边抓取 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..

但是,尽管这与Firebug中的预期文本(64076)相匹配,但是在使用Selenium WebDriver(Java)时找不到。

当我将XPath更改为:

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

它可以工作,但是它也会刮除我不想要的文本 Item model number:(我知道我可以使用regex解析结果,但是我试图理解为什么我的XPath无法正常工作因为我显然是通过text()而不是粗体字匹配实际的文本/编号

谢谢

6 个答案:

答案 0 :(得分:0)

这是因为XPath中的text()意味着可以找到TextNode,但对于Selenium仅支持查找并返回ElementNode。 Selenium还不支持属性节点,但XPath也支持。

您必须找到TextNode的父级(即ElementNode),然后使用正则表达式或split提取所需的字符串。

String xpath = "//ul/li[b[text()='Item model number:']][contains(. , '64076')]"
driver.findElement(By.xpath(xpath)).getText().split()[1]

答案 1 :(得分:0)

这是硒中的常见问题,因为它仅支持不包含text()的XPath 1.0。通常的方法是获取节点并调用getText()

Here是一个包装精美的函数,用于从子级获取没有任何文本的文本:

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

当然,您也可以使用字符串函数或正则表达式来提取有问题的字符串。但这可能需要您为每种情况编写自定义提取逻辑。

答案 2 :(得分:0)

您不能使用Selenium直接获取它,因为它是TextNode。 您可以使用JavaScript检查文本节点并获取它。

debug.Print

答案 3 :(得分:0)

@Bauban解答中的更多内容。 Selenium不允许使用文本节点定位元素。您可以尝试使用JavaScript的evaluate()方法,并使用JavascriptExecutor

来评估xpath

这是您的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());

您可以参考this链接以获取有关评估函数的更多详细信息。

答案 4 :(得分:0)

根据您共享的网址,提取this page项目型号:旁边的文本 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
    

答案 5 :(得分:0)

尝试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