7

我需要解析嵌套的 HTML 列表并将其转换为父子字典。鉴于此列表:

<ul>
  <li>Operating System
    <ul>
      <li>Linux
        <ul>
          <li>Debian</li>
          <li>Fedora</li>
          <li>Ubuntu</li>
        </ul>
      </li>
      <li>Windows</li>
      <li>OS X</li>
    </ul>
  </li>
  <li>Programming Languages
    <ul>
      <li>Python</li>
      <li>C#</li>
      <li>Ruby</li>
    </ul>
  </li>
</ul>

我想把它转换成这样的字典:

{
    'Operating System': {
        'Linux': {
            'Debian': None,
            'Fedora': None,
            'Ubuntu': None,
        },
        'Windows': None,
        'OS X': None,
    },
    'Programming Languages': {
        'Python': None,
        'C#': None,
        'Ruby': None,
    }
}

我最初的尝试是使用find_all('li', recursive=False). 它返回顶级项目(操作系统和编程语言)以及子项。

我怎么能用 BeautifulSoup 做到这一点?

4

1 回答 1

11

这是一种方法:

def dictify(ul):
    result = {}
    for li in ul.find_all("li", recursive=False):
        key = next(li.stripped_strings)
        ul = li.find("ul")
        if ul:
            result[key] = dictify(ul)
        else:
            result[key] = None
    return result

示例使用:

>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup("""
... <ul>
...   <li>Operating System
...     <ul>
...       <li>Linux
...         <ul>
...           <li>Debian</li>
...           <li>Fedora</li>
...           <li>Ubuntu</li>
...         </ul>
...       </li>
...       <li>Windows</li>
...       <li>OS X</li>
...     </ul>
...   </li>
...   <li>Programming Languages
...     <ul>
...       <li>Python</li>
...       <li>C#</li>
...       <li>Ruby</li>
...     </ul>
...   </li>
... </ul>
... """)
>>> ul = soup.body.ul
>>> from pprint import pprint
>>> pprint(dictify(ul), width=1)
{u'Operating System': {u'Linux': {u'Debian': None,
                                  u'Fedora': None,
                                  u'Ubuntu': None},
                       u'OS X': None,
                       u'Windows': None},
 u'Programming Languages': {u'C#': None,
                            u'Python': None,
                            u'Ruby': None}}
于 2013-07-25T06:39:54.793 回答