任何标签外的元素的getText()都无需在xpath

时间:2019-04-05 15:08:06

标签: java selenium selenium-webdriver xpath invalidselectorexception

因此,我需要在一个网页中获取一个特定的文本,该网页中的标签外或跨度标签后包含200多行文本。

我能够获得确切的xpath,

By outputVersion = By.xpath("//*[@class='output']/text()[contains(.,'TEXT THAT I NEED')]");
By outputVersion = By.xpath("//*[@class='timestamp']/following-sibling::text()[contains(.,'TEXT THAT I NEED')]");

尽管我提出并使用它的xpath上有text(),但每当我使用getText(),getAttribute(“ value”)和getAttribute(“)时,我都有org.openqa.selenium.InvalidSelectorException innerText”)。

实际的页面元素看起来像这样

<pre class="output">
    <span class="timestamp">time</span>
    "TEXT"

    <span class="timestamp">time</span>
    "TEXT"
    .
    .
    .
    .
    .
    <span class="timestamp">time</span>
    "TEXT THAT I NEED"  
    .
    .
    .
    .
    .
</pre>

有了这一点,我需要提出一个排除了text()的xpath。

请注意,<span class="timestamp">time</span>超过200多行带有不同的文本,并且会不时变化。另外,我需要的文本不在固定的行中,因此我依赖于contains

3 个答案:

答案 0 :(得分:1)

这是仅获取父文本的方法。

Java实现:

public String get_text_from_parent_by_postion(WebDriver driver, WebElement element, int textPosition) {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    return (String) js.executeScript("var parent = arguments[0];var textPosition = arguments[1]; var txtPosition = 0; var child = parent.firstChild; var textValue=''; while(child) { if (child.nodeType === 3){ if (txtPosition===(textPosition-1)){ textValue = child.textContent; break;}}else{txtPosition+=1;}child = child.nextSibling; } return textValue;", element, textPosition);
}

这是在您的情况下调用此方法的方法-

WebElement element = driver.findElement(By.xpath("//p[@class='output']"));
get_text_from_parent_by_postion(driver, element,3)

python实现:

        def get_text_from_parent_by_postion(element, textPosition=1):
    return driver.execute_script(
        """ var parent = arguments[0];
            var textPosition = arguments[1];
            var txtPosition = 0;
            var child = parent.firstChild;
            var textValue="";
            while(child) {
              if (child.nodeType === 3){                        
                if (txtPosition===(textPosition-1)){
                  textValue = child.textContent;                
                  break;
                }}else{txtPosition+=1;}
              child = child.nextSibling;
            }
        return textValue;""",
        element, textPosition).strip()

答案 1 :(得分:0)

"return document.evaluate(\"//*[@class='timestamp']/following-sibling::text()[contains(.,'TEXT THAT I NEED')]\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE,null);"

您可以使用Xpath,尝试将其传递给JavascriptExecutor,就像这样:

public String yourMethodName(WebDriver webDriver, String yourText) {
        String script = String.format("return document.evaluate(\"//*[@class='timestamp']/following-sibling::text()[contains(.,'%s')]\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE,null);", yourText);
        JavascriptExecutor js = (JavascriptExecutor) webDriver;
        return (String) js.executeScript(script);
}

答案 2 :(得分:0)

您可以使用以下代码执行javascript执行来评估xpath:

JavascriptExecutor js = (JavascriptExecutor)driver;
Object textYouWant= js.executeScript("var value = document.evaluate(\"//*[@class='timestamp']/following-sibling::text()[contains(.,'TEXT THAT I NEED')]\",document, null, XPathResult.STRING_TYPE, null ); return value.stringValue;");
System.out.println(textYouWant.toString().trim());

有关evaluate()的更多详细信息,请参见this