Преобразование списка HTML во вложенный список Python

Если у меня есть вложенный список html (неупорядоченный), который выглядит так:

<ul>
    <li><a href="Page1_Level1.html">Page1_Level1</a> 
    <ul>
        <li><a href="Page1_Level2.html">Page1_Level2</a> 
            <ul>
                <li><a href="Page1_Level3.html">Page1_Level3</a></li>
            </ul>
            <ul>
                <li><a href="Page2_Level3.html">Page2_Level3</a></li>
            </ul>
            <ul>
                <li><a href="Page3_Level3.html">Page3_Level3</a></li>
            </ul>
        </li>
    </ul>
    </li>
    <li><a href="Page2_Level1.html">Page2_Level1</a> 
    <ul>
        <li><a href="Page2_Level2.html">Page2_Level2</a></li>
    </ul>
    </li>
</ul>

Как мне сформировать из него вложенный список в Python? Например:

["Page1_Level1.html", ["Page1_Level2.html", ["Page1_Leve3.html", "Page2_Level3.html", "Page3_Level3.html"]], "Page2_Level1.html", ["Page2_Level2.html"]]

Я предполагаю, что такие библиотеки, как Beautiful Soup и HTML Parser, имеют средства для этого, но я не смог понять это. Спасибо за любую помощь / указатели!


person pmohandas    schedule 14.06.2014    source источник


Ответы (2)


Вы можете использовать рекурсивный подход:

from pprint import pprint
from bs4 import BeautifulSoup

text = """your html goes here"""

def find_li(element):
    return [{li.a['href']: find_li(li)}
            for ul in element('ul', recursive=False)
            for li in ul('li', recursive=False)]


soup = BeautifulSoup(text, 'html.parser')
data = find_li(soup)
pprint(data)

Отпечатки:

[{u'Page1_Level1.html': [{u'Page1_Level2.html': [{u'Page1_Level3.html': []},
                                                 {u'Page2_Level3.html': []},
                                                 {u'Page3_Level3.html': []}]}]},
 {u'Page2_Level1.html': [{u'Page2_Level2.html': []}]}]

К вашему сведению, вот почему мне пришлось использовать html.parser здесь:

person alecxe    schedule 14.06.2014
comment
Это потрясающе! Большое спасибо! - person pmohandas; 14.06.2014

Это обзор возможного решения

# variable 'markup' contains the html string
from bs4 import BeautifulSoup
soup = BeautifulSoup(markup)
for a in soup.descendants:
   # construct a nested list when going thru the descendants
   print id(a), id(a.parent) if a.parent else None, a
person Anthony Kong    schedule 14.06.2014