Использование lxml для поиска порядка текста и подэлементов - PullRequest
0 голосов
/ 14 июля 2010

Допустим, у меня есть следующий HTML:

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

Я знаю, как получить текст и подэлементы вложенного div, используя lxml.html.Но есть ли способ итеративного доступа как к тексту, так и к субэлементам, который сохраняет порядок?Другими словами, я хочу знать, где появляется «свободный текст» div относительно изображений.Я хотел бы знать, что «text1» появляется перед первым inner-div, и что text2 появляется между двумя inner-div и т. Д.

1 Ответ

2 голосов
/ 14 июля 2010

Интерфейс 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 s и дает два кортежа с первым элементом 'tag', 'text' или 'tail', чтобы помочь вам различить. Я полагаю, что это не ваш идеальный формат, но не должно быть трудно превратить его во что-то более по вашему вкусу; -).

...