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

发布于 2024-09-09 02:30:55 字数 313 浏览 2 评论 0原文

假设我有以下 HTML:

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

我知道如何使用 lxml.html 获取封闭 div 的文本和子元素。但是有没有一种方法可以以迭代方式访问文本和子元素,同时保留顺序?换句话说,我想知道 div 的“自由文本”相对于图像出现在哪里。我希望能够知道“text1”出现在第一个内部 div 之前,并且 text2 出现在两个内部 div 之间,等等。

Let's say I have the following HTML:

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

I know of how to get the text and subelements of the enclosing div using lxml.html. But is there a way to access both text and sub elements in an iterative manner, that preserves order? In other words, I want to know where the "free text" of the div appears relative to the images. I would like to be able to know that "text1" appears before the first inner-div, and that text2 appears between the two inner-divs, etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

彼岸花ソ最美的依靠 2024-09-16 02:30:55

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'

根据您的 lxml/elementtree 版本,您可以需要拼写迭代器方法 .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',帮助您区分。我想这不是您理想的格式,但将其塑造成更符合您喜好的格式应该不难;-)。

The elementtree interface, which lxml also offers, supports that -- e.g. with the built-in element tree in 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'

Depending on your version of lxml/elementtree, you may need to spell the iterator method .getiterator() instead of .iter().

If you need a single generator that will yields tags and texts in order, for example:

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

This basically removes the Nones and yields two-tuples with a first item of 'tag', 'text', or 'tail', to help you distinguish. I imagine this is not your ideal format, but it should not be hard to mold it into something more to your liking;-).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文