我通过xpath废弃了一些html,然后我转换成了etree。类似的东西:
<td> text1 <a> link </a> text2 </td>
但是当我调用element.text时,我只得到text1(它必须在那里,当我在FireBug中检查我的查询时,元素的文本被突出显示,嵌入的锚元素之前和之后的文本......
答案 0 :(得分:15)
使用element.xpath("string()")
或lxml.etree.tostring(element, method="text")
- 请参阅the documentation。
答案 1 :(得分:6)
作为对那些可能像我一样懒惰的人的公共服务。以上是您可以运行的一些代码。
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
答案 2 :(得分:5)
对我来说看起来像一个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
答案 3 :(得分:4)
另一件似乎很有效的方法是将文本从元素中删除"".join(element.itertext())
答案 4 :(得分:1)
def get_text_recursive(node):
return (node.text or '') + ''.join(map(get_text_recursive, node)) + (node.tail or '')
答案 5 :(得分:1)
<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])
答案 6 :(得分:0)
如果element
等于<td>
。您可以执行以下操作。
element.xpath('.//text()')
它将为您提供self
中所有文本元素的列表(点的含义)。 //
表示它将占用所有元素,最后text()
是提取文本的函数。
答案 7 :(得分:0)
element.xpath('normalize-space()') also works.