lxml.etree,element.text未返回元素的全部文本

19 投票
8 回答
13896 浏览
提问于 2025-04-16 10:26

我通过xpath抓取了一些html内容,然后把它转换成了一个etree。大概是这样的:

<td> text1 <a> link </a> text2 </td>

但是当我调用element.text的时候,我只得到了text1(这个文本应该是存在的,当我在FireBug中检查我的查询时,元素的文本会被高亮显示,包括嵌入的锚点元素前后的文本...)

8 个回答

7

我觉得这看起来像是lxml的一个bug,不过如果你看看文档的话,会发现这是设计上的问题。我是这样解决的:

def node_text(node):
    if node.text:
        result = node.text
    else:
        result = ''
    for child in node:
        if child.tail is not None:
            result += child.tail
    return result
10

为了帮助那些可能和我一样懒的人,这里有一些你可以运行的代码。

from lxml import etree

def get_text1(node):
    result = node.text or ""
    for child in node:
        if child.tail is not None:
            result += child.tail
    return result

def get_text2(node):
    return ((node.text or '') +
            ''.join(map(get_text2, node)) +
            (node.tail or ''))

def get_text3(node):
    return (node.text or "") + "".join(
        [etree.tostring(child) for child in node.iterchildren()])


root = etree.fromstring(u"<td> text1 <a> link </a> text2 </td>")

print root.xpath("text()")
print get_text1(root)
print get_text2(root)
print root.xpath("string()")
print etree.tostring(root, method = "text")
print etree.tostring(root, method = "xml")
print get_text3(root)

运行结果是:

snowy:rpg$ python test.py 
[' text1 ', ' text2 ']
 text1  text2 
 text1  link  text2 
 text1  link  text2 
 text1  link  text2 
<td> text1 <a> link </a> text2 </td>
 text1 <a> link </a> text2 
18

你可以使用 element.xpath("string()") 或者 lxml.etree.tostring(element, method="text") 来获取元素的文本内容。具体的用法可以参考 这份文档

撰写回答