使用lxml查找文本和子元素的顺序

0 投票
1 回答
836 浏览
提问于 2025-04-16 01:17

假设我有以下的HTML代码:

<div>
text1
<div>
  t1
</div>
text2
<div>
  t2
</div>
text3
</div>

我知道怎么用lxml.html来获取包裹的div里的文本和子元素。但是有没有办法以一种循环的方式来访问这些文本和子元素,并且保持它们的顺序呢?换句话说,我想知道这个div里的“自由文本”相对于图片的位置。我希望能知道“text1”是在第一个内层div之前出现的,而“text2”是在两个内层div之间出现的,等等。

1 个回答

2

elementtree 接口是 lxml 也提供的一种功能,它支持这个功能,比如在 Python 2.7 中的内置元素树:

>>> from xml.etree import ElementTree as et
>>> x='''<div>
... text1
... <div>
...   t1
... </div>
... text2
... <div>
...   t2
... </div>
... text3
... </div>'''
>>> t=et.fromstring(x)
>>> for el in t.iter():
...   print '%s: %r, %r' % (el.tag, el.text, el.tail)
... 
div: '\ntext1\n', None
div: '\n  t1\n', '\ntext2\n'
div: '\n  t2\n', '\ntext3\n'

根据你使用的 lxmlelementtree 的版本,你可能需要用 .getiterator() 来代替 .iter()

如果你需要一个可以按顺序生成标签和文本的单一生成器,比如:

def elements_and_texts(t):
    for el in t.iter():
        yield 'tag', el.tag
        if el.text is not None:
            yield 'text', el.text
        if el.tail is not None:
            yield 'tail', el.tail

这个方法基本上会去掉 None,并生成包含两个元素的元组,第一个元素是 'tag''text''tail',这样可以帮助你区分它们。我想这可能不是你理想的格式,但把它调整成你喜欢的样子应该不难;-)。

撰写回答