掌握LXML非连续文本/ ElementTree的
假设我有这种HTML,从中我需要选择“文本2”使用LXML/ElementTree的:掌握LXML非连续文本/ ElementTree的
<div>text1<span>childtext1</span>text2<span>childtext2</span>text3</div>
如果我已经有div元素作为mydiv,那么mydiv.text只返回“text1”。
使用itertext()看起来有问题或麻烦,因为它遍历div下的整个树。
是否有任何简单/优雅的方式从元素中提取非第一个文本块?
好,lxml.etree提供完整的XPath支持,允许您解决文本项:
>>> import lxml.etree
>>> fragment = '<div>text1<span>childtext1</span>text2<span>childtext2</span>text3</div>'
>>> div = lxml.etree.fromstring(fragment)
>>> div.xpath('./text()')
['text1', 'text2', 'text3']
doc.xpath('/ div/text()')[1:2]会给你非第一个文本元素 – shahjapan 2010-09-24 06:51:58
好吧,“一种方式来提取非第一个文本块”包括许多可能性后,你得到所有文本项列表,如'random.choice(div.xpath('./text()')[1:])或set(div.xpath('./ text()')[1: ])。流行()'。但是,由于OP知道足够了解lxml,所以我认为数字列表操作就是小豆。 – 2010-09-24 07:43:35
这样的文本将在您的元素的子元素的tail
属性中。如果你的元素是在elem
则:
elem[0].tail
会给你的第一个孩子的元素中的尾文本,你的情况"text2"
你正在寻找。
正如llasram所说,任何不在text
属性中的文本都将在子节点的tail
属性中。
作为一个例子,这里的提取文本块(第一和其他)中的一个节点的所有最简单的方法:
html = '<div>text1<span>childtext1</span>text2<span>childtext2</span>text3</div>'
import lxml.html # ...or lxml.etree as appropriate
div = lxml.html.fromstring(html)
texts = [div.text] + [child.tail for child in div]
# Result: texts == ['text1', 'text2', 'text3']
# ...and you are guaranteed that div[x].tail == texts[x+1]
# (which can be useful if you need to access or modify the DOM)
如果你宁愿牺牲这层关系,以防止texts
从可能含有空字符串,你可以使用它代替:
texts = [div.text] + [child.tail for child in div if child.tail]
我还没有与普通的旧STDLIB ElementTree的测试,这一点,但它应该与工作了。 (事只有一次,我看到了巴蒂尔Holloway的具体LXML-解决发生在我身上),我只是喜欢LXML因为它有更好的支持HTML的ideosyncracies我通常已经安装了lxml.html.clean
使用node.text_content()
让所有节点下面的文本,作为一个字符串。
这看起来像一个错误。你有没有尝试过使用'findtext(path)'? – 2010-09-18 06:55:43
因为我的回答显然不能回答你的问题,你能否进一步解释你在找什么? – llasram 2010-09-19 09:18:51