如何使用xpath表达式从项目型号中删除文本64076

问题描述 投票:0回答:6

我正在尝试使用以下XPath表达式刮取项目型号旁边的文本64076:在this page上:

//*[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')]

它工作但它也刮擦文本项目模型编号:我不想要(我知道我可以使用正则表达式解析结果,但我试图理解为什么我的XPath不工作,因为我明显匹配实际的文本/数字通过text(),而不是粗体文字)

谢谢

java selenium selenium-webdriver xpath webdriverwait
6个回答
0
投票

这是因为XPath中的text()意味着找到TextNode,但是Selenium只支持查找和返回ElementNode。 Selenium也不支持属性节点,但XPath支持。

你必须找到TextNode的父(它是一个ElementNode),然后使用正则表达式或拆分来提取你想要的刺痛。

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

0
投票

这是selenium中的常见问题,因为它只支持不包含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;
}

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


0
投票

您不能使用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
投票

更多@Bauban答案。 Selenium不允许使用文本节点定位元素。您可以尝试使用evaluate() JavaScript方法并使用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链接以获取有关评估功能的更多详细信息。


0
投票

根据你分享的url提取文本64076旁边的文本:在this page上,因为它是一个文本节点,你需要使用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
投票

尝试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
© www.soinside.com 2019 - 2024. All rights reserved.