Используя lxml, как я могу найти и собрать все элементы между тегами определенного типа? - PullRequest
0 голосов
/ 22 октября 2011

У меня есть HTML-документ с внутренними ссылками (т. Е. <a name="blah"></a> теги) в начале определенных разделов.

Я хочу посетить каждую внутреннюю ссылку и рекурсивно перехватить весь текст, содержащийся во всех элементах.

Например, между этими двумя ссылками:

<A name='G27866101'>
<DIV align="left" style="margin-left: 0%; margin-right: 0%; font-size: 10pt; font-family: Arial, Helvetica; color: #000000; background: transparent">
    <B><FONT style="font-family: 'Times New Roman', Times">About This Section</FONT></B>
</DIV>
</A>

<DIV align="left" style="margin-left: 0%; margin-right: 0%; text-indent: 3%; font-size: 10pt; font-family: 'Times New Roman', Times; color: #000000; background: transparent">
    This section is part of a registration that we filed with the proper authorities ... blah ... for more information.
</DIV>

<A name='G27866102'>

Я хочу получить:

About This Section

This section is part of a registration that we filed with the proper authorities ... blah ... for more information.

И поскольку элементы между ссылками могут иметь вложенные элементы, я хочу также получить весь этот текст (т. Е. Просмотреть все дочерние элементы и получить этот текст).

Например, из этого:

<A name='G27866102'>
<DIV align="left" style="margin-left: 0%; margin-right: 0%; font-size: 10pt; font-family: Arial, Helvetica; color: #000000; background: transparent">
    <B><FONT style="font-family: 'Times New Roman', Times">Additional Information</FONT></B>
</DIV>
</A>

<DIV align="left" style="margin-left: 0%; margin-right: 0%; text-indent: 3%; font-size: 10pt; font-family: 'Times New Roman', Times; color: #000000; background: transparent">
    As permitted by house rules, this section is ... 
    <DIV><FONT style="font-family: 'Times New Roman', Times">There's nested text here<FONT></DIV>
    ... blah ... the actual document.
</DIV>

Я бы хотел получить:

Additional Information

As permitted by house rules, this section is ... There's nested text here ... blah ... the actual document.

Я знаю об использовании findall('//a') и проверке хэша attrib на наличие ключа 'name', но это просто дает мне элементы тега <a name="blah"></a>.

В идеале я хотел бы иметь возможность определить рекурсивную get_all_nodes_in_between() функцию, которая будет работать следующим образом:

anchors = html.findall('//a')
for i, anchor in enumerate(anchors):
    if anchor.attrib.has_key('name'):
        all_elements = get_all_nodes_in_between(anchor, anchor[(i+1)]

Как это можно сделать?

1 Ответ

0 голосов
/ 22 октября 2011

Вы можете сделать это в BeautifulSoup, проверив тег DIV и собрав все данные в нем:

Отредактированный код из комментариев:

    from BeautifulSoup import BeautifulSoup
    import re

    html ='''
        <A name='G27866101'>
<DIV align="left" style="margin-left: 0%; margin-right: 0%; font-size: 10pt; font-family: Arial, Helvetica; color: #000000; background: transparent">
    <B><FONT style="font-family: 'Times New Roman', Times">About This Section</FONT></B>
</DIV>
</A>

<DIV align="left" style="margin-left: 0%; margin-right: 0%; text-indent: 3%; font-size: 10pt; font-family: 'Times New Roman', Times; color: #000000; background: transparent">
    This section is part of a registration that we filed with the proper authorities ... blah ... for more information.
</DIV>

<A name='G27866102'>
    '''
    soup = BeautifulSoup(html)

    for item in soup.findAll('div'):
        print ''.join(item.findAll(text=True))

выходные данные:

About This Section


This section is part of a registration that we filed with the proper authorities ... blah ... for more information.
...