Python和Selenium - 获取排除子节点文本的文本

Álv*_*anz 7 python selenium python-3.x selenium-webdriver

使用Python 3.

假设:

<whatever>
  text
  <subchild>
    other
  </subchild>
</whatever>
Run Code Online (Sandbox Code Playgroud)

如果我这样做:

elem = driver.find_element_by_xpath("//whatever")

elem.text包含"text other"

如果我这样做:

elem = driver.find_element_by_xpath("//whatever/text()[normalize-space()]")

elem不是Webelement.

我如何继续只抓"文本"(而不是"其他")?

Id est:仅抓取直接节点中的文本,而不抓取子节点.

更新:

原始HTML是:

<div class="border-ashes the-code text-center">
VIVEGRPN
  <span class="cursor"></span>
  <button class="btn btn-ashes zclip" data-clipboard-target=".the-code" data-coupon-code="VklWRUdSUE4=">
  <span class="r">Hen, la.</span>
</div>
Run Code Online (Sandbox Code Playgroud)

Rad*_*dan 6

我最近遇到了类似的问题,硒总是给我元素内的所有文本,包括跨度。我最终用换行符“\n”分割了字符串。例如

all_text = driver.find_element_by_xpath(xpath).text
req_text = str.split(str(all_text ), "\n")[0]
Run Code Online (Sandbox Code Playgroud)


Guy*_*Guy 5

您可以从所有文本中删除子节点文本

all_text = driver.find_element_by_xpath("//whatever").text
child_text = driver.find_element_by_xpath("//subchild").text

parent_text = all_text.replace(child_text, '')
Run Code Online (Sandbox Code Playgroud)

  • 如果它们都有相同的文本,这可能会导致问题 (10认同)

jcr*_*crs 5

请记住,@Guy 提到 的替换方法不适用于许多结构。

例如,具有以下结构:

<div>
    Hello World
    <b>e</b>
</div>
Run Code Online (Sandbox Code Playgroud)

父文本将是Hello World e,子文本将是e,替换将导致Hllo World 而不是Hello World。

一个安全的解决方案

要以安全的方式获取元素自己的文本,您必须遍历节点的子节点,并连接文本节点。由于在纯 Selenium 中无法做到这一点,因此必须执行 JS 代码。

OWN_TEXT_SCRIPT = "if(arguments[0].hasChildNodes()){var r='';var C=arguments[0].childNodes;for(var n=0;n<C.length;n++){if(C[n].nodeType==Node.TEXT_NODE){r+=' '+C[n].nodeValue}}return r.trim()}else{return arguments[0].innerText}"
parent_text = driver.execute_script(OWN_TEXT_SCRIPT, elem)
Run Code Online (Sandbox Code Playgroud)

该脚本是这个简单函数的缩小版本:

if (arguments[0].hasChildNodes()) {
    var res = '';
    var children = arguments[0].childNodes;
    for (var n = 0; n < children.length; n++) {
        if (children[n].nodeType == Node.TEXT_NODE) {
            res += ' ' + children[n].nodeValue;
        }
    }
    return res.trim()
}
else {
    return arguments[0].innerText
}
Run Code Online (Sandbox Code Playgroud)