如何从父元素获取文本并从子元素中排除文本(C# Selenium)

How to get text from parent element and exclude text from children (C# Selenium)

在 Selenium 中是否可以仅从父元素而不是其子元素获取文本?

示例: 假设我有以下代码:

<div class="linksSection>
  <a href="https://www.google.com/" id="google">Google Link
    <span class="helpText">This link will take you to Google's home page.</span>
  </a>
  ...
</div>

在 C#(或任何语言)中,我将有:

string linktext = driver.FindElement(By.CssSelector(".linksSection > a#google")).Text;
Assert.AreEqual(linkText, "Google Link", "Google Link fails text test.");

但是,链接文本将有 "Google LinkThis link will take you to Google's home page."

如果不进行一系列字符串操作(例如获取所有子元素的文本并从父元素的结果文本中减去该文本),是否有办法只从父元素获取文本?

这是 selenium 中的 common problem,因为您不能直接访问文本节点 - 换句话说,您的 XPath 表达式和 CSS 选择器必须指向实际元素。

以下是针对您的问题的可能解决方案列表:

  • 获取 parent 元素的文本,对于每个 child,获取文本并将其从 parent 的文本中删除。您剩下的是所需的文本 - Google Link 在您的情况下。
  • 如果你想得到 Google Link 只是为了做出断言,你可以检查 parent 的文本 s 是否带有 Google Link。参见 StringAssert.StartsWith()
  • 获取 parent 文本的 outerHTML 并提供给 HTML 解析器,例如 Html Agility Pack。沿着这些线的东西:

    string outerHTML = driver.FindElement(By.CssSelector(".linksSection > a#google")).GetAttribute("outerHTML");
    
    HtmlDocument html = new HtmlDocument();
    html.LoadHtml(outerHTML);
    
    HtmlAgilityPack.HtmlNode a = html.DocumentNode.SelectNodes("//a[@id='google']");
    HtmlNode text = strong.SelectSingleNode("following-sibling::text()");
    
    Console.WriteLine(text.InnerText.Trim());
    

可以通过三种方式完成这项工作。

  1. 将子节点中不需要的文本替换为'''',逻辑与其他答案一样。
  2. 使用 js :
    private static String OWN_TEXT_JS = "arr=[];content=document.querySelector(arguments[0]);for(i=0,len=content.childNodes.length;i<len;i++){if(content.childNodes[i].nodeType===3){arr.push(content.childNodes[i].nodeValue);}}str=arr.join(\"\"); return str;";
    Object result = ((JavascriptExecutor) WebDriver).executeScript(OWN_TEXT_JS, path);
    if (!(result instanceof String))
       return null;
    else 
       return (String) result;

  1. 使用html解析器,在java中是jsoup。

    element= webDriver.findElement...
    String result = Jsoup.parse(element.getAttribute("outerHTML")).selectFirst(element.getTagName()).ownText();

    WebElement webElement = webDriver.findElement(By.xpath("/html"));
    Jsoup.parse(webElement.getAttribute("outerHTML")).selectFirst(csspath).ownText();