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

时间:2017-07-21 13:00:09

标签: python python-3.x selenium

使用 Python 3

假设

<whatever>

    text

    <subchild>
    other
    </subchild>

</whatever>

如果我

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>

4 个答案:

答案 0 :(得分:4)

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

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, '')

答案 1 :(得分:3)

我最近遇到过类似的问题,其中selenium总是给我包含元素内的所有文本,包括跨度。我最后用换行符&#34; \ n&#34;分割字符串。例如。

all_text = driver.find_element_by_xpath(xpath).text
req_text = str.split(str(all_text ), "\n")[0]

答案 2 :(得分:1)

请记住,replacement approach mentioned by @Guy 对许多结构都无效

例如,具有以下结构:

<div>
    Hello World
    <b>e</b>
</div>

父文本将为Hello World e,子文本将为e,替换后的结果将为Hllo World,而不是Hello World

安全的解决方案

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

OWN_TEXT_SCRIPT = "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()"
parent_text = driver.execute_script(OWN_TEXT_SCRIPT, elem)

该脚本是此简单功能的简化版本:

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();

答案 3 :(得分:0)

您可以首先从元素中提取outerHTML,然后使用soup构建BeautifulSoup,然后删除所需的任何元素。

小例子:

el = driver.find_element_by_css_selector('whatever')
outerHTML = el.get_attribute('outerHTML')
soup = BeautifulSoup(outerHTML)
inner_elem = soup.select('subchild')[0].extract()
text_inner_elem = inner_elem.text
text_outer_elem = soup.text