如何使用selenium从不包含它的子元素的元素中获取Text

时间:2016-09-28 07:43:16

标签: java selenium

HTML

<div id='one'>
    <button id='two'>i am button</button>
    <button id='three'>i am button</button>
    i am div
</div>

代码

driver.findElement(By.id('one')).getText();

6 个答案:

答案 0 :(得分:6)

我已经看到这个问题在最后一年左右出现了几次,我想尝试写这个功能......所以你去吧。它接受父元素并删除每个子元素的textContent,直到剩下的是textNode。我已经在你的HTML上对它进行了测试,但它确实有用。

/**
 * Takes a parent element and strips out the textContent of all child elements and returns textNode content only
 * 
 * @param e
 *            the parent element
 * @return the text from the child textNodes
 */
public static String getTextNode(WebElement e)
{
    String text = e.getText().trim();
    List<WebElement> children = e.findElements(By.xpath("./*"));
    for (WebElement child : children)
    {
        text = text.replaceFirst(child.getText(), "").trim();
    }
    return text;
}

你称之为

System.out.println(getTextNode(driver.findElement(By.id("one"))));

答案 1 :(得分:0)

警告:初始解决方案(深层次)不起作用
我针对Selenium WebDrive打开了enhancement request: 2840,针对W3C WebDrive规范打开了another one - 投票越多,他们就越早得到足够的关注(人们可以希望)。在此之前,@ shivansh在另一个答案(通过Selenium执行JavaScript)中提出的解决方案仍然是唯一的选择。这是该解决方案的Java改编(收集所有文本节点,丢弃所有只有空格,用\ t分隔剩余的文本节点):

WebElement e=driver.findElement(By.xpath("//*[@id='one']"));
if(driver instanceof JavascriptExecutor) {
  String jswalker=
      "var tw = document.createTreeWalker("
     +   "arguments[0],"
     +   "NodeFilter.SHOW_TEXT,"
     +   "{ acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT;} },"
     +    "false"
     + ");"
     + "var ret=null;"
     + "while(tw.nextNode()){"
     +   "var t=tw.currentNode.wholeText.trim();"
     +   "if(t.length>0){" // skip over all-white text values
     +      "ret=(ret ? ret+'\t'+t : t);" // if many, tab-separate them
     +   "}"
     + "}"
     + "return ret;" // will return null if no non-empty text nodes are found
  ;
  Object val=((JavascriptExecutor) driver).executeScript(jswalker, e);
  // ---- Pass the context node here ------------------------------^
  String textNodesTabSeparated=(null!=val ? val.toString() : null);
  // ----^ --- this is the result you want
}

参考文献:

TreeWalker - 受所有浏览器支持

Selenium Javascript Executor

初步建议的解决方案 - 无法正常工作 - 请参阅enhancement request: 2840

driver.findElement(By.id('one')).find(By.XPath("./text()").getText();

在一次搜索中

driver.findElement(By.XPath("//[@id=one]/text()")).getText();

请参阅XPath spec/Location Paths child::text()选择器。

答案 2 :(得分:0)

我使用如下函数:

{{1}}

答案 3 :(得分:0)

给定解决方案的类似解决方案,但我没有使用javascript或将文本设置为“”,而是删除了xml中的元素,然后获取了文本。

问题: 需要“无子级根元素”中的文本,其中子级可以是x层深,并且根中的文本可以与其他元素中的文本相同。

该解决方案将webelement视为xml,并用void替换子元素,因此仅保留根。

然后分析结果。就我而言,这似乎可行。

我仅在Groovy的环境中验证了此代码。不知道它是否可以在Java中运行而无需修改。基本上,您需要用Java库替换xml的groovy库,然后我就走了。

对于代码本身,我有两个参数: -WebElement el -布尔严格

当strict为true时,实际上仅考虑根。如果strict为false,则将保留标记标签。我在此白名单中包括p,b,i,strong,em,mark,small,del,ins,sub,sup。

逻辑是:

  1. 管理列入白名单的标签
  2. 获取元素作为字符串(xml)
  3. 解析为xml对象
  4. 将所有子节点设置为空
  5. 解析并获取文本

到目前为止,这似乎一直在解决。

您可以在此处找到代码:Github Code

答案 4 :(得分:0)

var outerElement = driver.FindElement(By.XPath("a"));
var outerElementTextWithNoSubText = outerElement.Text.Replace(outerElement.FindElement(By.XPath("./*")).Text, "");

答案 5 :(得分:-1)

您可以使用javascript查找文字。下面是一个c#示例

var script = @"var lastTextNode = document.createTreeWalker(arguments[0], NodeFilter.SHOW_TEXT, null, false).lastChild();
                       if(lastTextNode == null)
                            return null;
                        return lastTextNode.textContent;";

var element = driver.FindElement(By.id('one'));

IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
elementText = js.ExecuteScript(script, element).ToString();