【问题标题】:Retrieve Text Between Two Child Elements With Text使用文本检索两个子元素之间的文本
【发布时间】:2018-07-09 03:58:00
【问题描述】:

我想知道是否有任何方法可以轻松检索夹在带有文本的两个子元素之间的文本?在这种特殊情况下,我希望提取文本 USD

<div class="indemandProgress-raised ng-binding">
    <span class="indemandProgress-raisedAmount ng-binding" gogo-test="raised">
        $6,811,034
    </span>
    USD
    <span class="ng-binding">
        total funds raised
    </span>
</div>

浏览器中代码的实际格式

<div class="indemandProgress-raised ng-binding">
<span class="indemandProgress-raisedAmount ng-binding" gogo-test="raised">$6,811,034</span> USD <span class="ng-binding">total funds raised</span>
</div>

这是否可以单独使用 XPATH 或者我必须提取所有文本然后解析它?

它必须与 Selenium 一起使用。

【问题讨论】:

    标签: python selenium xpath


    【解决方案1】:

    您已经接受了答案,但请注意text.split()[1] 是非常不可靠的解决方案,它可能不适用于其他(大多数)情况。例如,如果第一个文本节点包含空格

    $ 6,811,034
    

    你可以试试这个解决方案:

    element = browser.find_element_by_class_name('indemandProgress-raisedAmount')
    result = browser.execute_script('return arguments[0].childNodes[2].textContent;', element).strip()
    

    注意div 有以下 5 个子节点:

    1. 空字符串(索引0
    2. span 节点(索引1
    3. 文本节点"USD"(索引2
    4. 另一个span(索引3
    5. 另一个空字符串(索引4

    您需要获取第三个子节点的文本内容,childNodes[2].textContent 允许您这样做

    【讨论】:

    • def 很高兴知道,但在数百个案例中,browser.find_element_by_xpath(...).text 总是返回类似于$107,866 USD total funds raised 的输出。
    • 在您的示例中,result = browser.execute_script('return arguments[0].childNodes[2].textContent;', element).strip()element 作为 arguments 传入的吗?
    • 是的。 arguments[0] == element。这只是browser.execute_script('return document.querySelector(".indemandProgress-raisedAmount").childNodes[2].textContent;').strip()的简化语法
    • 好有趣。这很酷,您如何使用 selenium 选择元素,将其存储为变量,然后将其作为变量传递给 javascript
    【解决方案2】:

    像使用 xpath 2.0+ 一样尝试:

    //div[@class="indemandProgress-raised ng-binding"]/text()
    

    Test Demo


    在 Selenium 中,您不能使用返回属性或文本节点的 XPath,因为仅支持节点。

    要获取您想要的文本,您可以使用 Javascript 从文本节点中提取它。 或者选择节点然后使用.text

    result = browser.find_element_by_xpath('//div[contains(@class, "indemandProgress-raisedAmount")]').text.split()[1]
    

    因此,最终,在 Selenium 中使用 XPath /text() 是不可能的,您必须依赖所概述的替代方法。

    【讨论】:

    • 已经试过了。不适用于硒。我想我应该将其添加到问题中。我的如果您有兴趣:WebDriverException: Message: TypeError: Expected an element or WindowProxy, got: [object Text] {}
    • 你可以选择带有.text的文本节点...无论如何,JS没用,因为我可以简单地使用x = browser.find_element_by_xpath(...).text.split()[1]
    • "在 Selenium 中使用 XPath /text() 是不可能的"
    • 所以在 selenium 环境中使用 xpath 绝对不可能?
    • 不幸的是,据我(有限的)知识,情况就是这样。这是answer that states the same
    【解决方案3】:

    您不能单独使用 XPath,但您可以使用 Javascript 执行器并获取文本节点。您没有指定语言,所以这里有一个在 C# 中执行此操作的方法:

    /// <summary>
    /// Returns the text of the specified child text node.
    /// </summary>
    /// <param name="parentElement">The parent <see cref="IWebElement"/> of the desired text node.</param>
    /// <param name="index">The index of the childNode collection relative to parentElement</param>
    /// <returns>The text of the specified child text node.</returns>
    public string GetChildTextNode(IWebElement parentElement, int index = 0)
    {
        string s = (string)((IJavaScriptExecutor)driver).ExecuteScript("return arguments[0].childNodes[arguments[1]].textContent;", parentElement, index);
        return s.Trim();
    }
    

    在这种情况下,您可以这样称呼它

    IWebElement e = Driver.FindElement(By.CssSelector("div.indemandProgress-raised"));
    string s = GetChildTextNode(e, 2);
    

    【讨论】:

    • myb.我添加了一个 python 标签
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-04
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多