17

我通过 xpath 报废了一些 html,然后将其转换为 etree。与此类似的东西:

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

但是当我调用element.text时,我只得到text1(它必须在那里,当我在FireBug中检查我的查询时,元素的文本被突出显示,嵌入锚元素之前和之后的文本......

4

8 回答 8

18

使用element.xpath("string()")lxml.etree.tostring(element, method="text")- 参见文档

于 2011-01-23T01:56:33.650 回答
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 
于 2013-10-06T13:19:49.660 回答
7

对我来说看起来像一个 lxml 错误,但如果您阅读文档,则根据设计。我已经这样解决了:

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
于 2011-09-21T13:09:35.767 回答
6

从元素中提取文本似乎效果很好的另一件事是"".join(element.itertext())

于 2014-04-06T08:04:48.307 回答
3
<td> text1 <a> link </a> text2 </td>

它是这样的(忽略空格):

td.text == 'text1'
a.text == 'link'
a.tail == 'text2'

如果您不想要子元素内的文本,那么您可以只收集它们的尾巴:

text = td.text + ''.join([el.tail for el in td])
于 2013-12-08T00:49:46.840 回答
1
def get_text_recursive(node):
    return (node.text or '') + ''.join(map(get_text_recursive, node)) + (node.tail or '')
于 2012-01-26T03:26:46.017 回答
0
element.xpath('normalize-space()') also works.
于 2017-07-24T03:59:14.047 回答
0

如果element等于<td>。您可以执行以下操作。

element.xpath('.//text()')

它将为您提供所有文本元素的列表self(点的含义)。//意味着它将获取所有元素,最后text()是提取文本的功能。

于 2017-05-23T18:51:37.873 回答