BeautifulSoup:如何从包含一些嵌套 <ul> 的 <ul> 列表中提取所有 <li>?

Posted

技术标签:

【中文标题】BeautifulSoup:如何从包含一些嵌套 <ul> 的 <ul> 列表中提取所有 <li>?【英文标题】:BeautifulSoup: How do I extract all the <li>s from a list of <ul>s that contains some nested <ul>s? 【发布时间】:2011-05-20 18:20:11 【问题描述】:

我是一名新手程序员,试图通过构建一个脚本来抓取http://en.wikipedia.org/wiki/2000s_in_film 并提取“电影标题(年份)”列表,从而进入 Python。 我的 html 源代码如下所示:

<h3>Header3 (Start here)</h3>
<ul>
    <li>List items</li>
    <li>Etc...</li>
</ul>
<h3>Header 3</h3>
<ul>
    <li>List items</li>
    <ul>
        <li>Nested list items</li>
        <li>Nested list items</li></ul>
    <li>List items</li>
</ul>
<h2>Header 2 (end here)</h2>

我想要在第一个 h3 标记之后并在下一个 h2 标记处停止的所有 li 标记,包括所有嵌套的 li 标记。

firstH3 = soup.find('h3')

...正确地找到了我想开始的地方。

firstH3 = soup.find('h3') # Start here
uls = []
for nextSibling in firstH3.findNextSiblings():
    if nextSibling.name == 'h2':
        break
    if nextSibling.name == 'ul':
        uls.append(nextSibling)

...给我一个列表 uls,每个列表都有我需要的 li 内容。

uls 列表摘录:

<ul>
...
    <li><i><a href="/wiki/Agent_Cody_Banks" title="Agent Cody Banks">Agent Cody Banks</a></i> (2003)</li>
    <li><i><a href="/wiki/Agent_Cody_Banks_2:_Destination_London" title="Agent Cody Banks 2: Destination London">Agent Cody Banks 2: Destination London</a></i> (2004)</li>
    <li>Air Bud series:
        <ul>
            <li><i><a href="/wiki/Air_Bud:_World_Pup" title="Air Bud: World Pup">Air Bud: World Pup</a></i> (2000)</li>
            <li><i><a href="/wiki/Air_Bud:_Seventh_Inning_Fetch" title="Air Bud: Seventh Inning Fetch">Air Bud: Seventh Inning Fetch</a></i> (2002)</li>
            <li><i><a href="/wiki/Air_Bud:_Spikes_Back" title="Air Bud: Spikes Back">Air Bud: Spikes Back</a></i> (2003)</li>
            <li><i><a href="/wiki/Air_Buddies" title="Air Buddies">Air Buddies</a></i> (2006)</li>
        </ul>
    </li>
    <li><i><a href="/wiki/Akeelah_and_the_Bee" title="Akeelah and the Bee">Akeelah and the Bee</a></i> (2006)</li>
...
</ul>

但我不确定从这里去哪里。


更新:

最终代码:

lis = []
    for ul in uls:
        for li in ul.findAll('li'):
            if li.find('ul'):
                break
            lis.append(li)

    for li in lis:
        print li.text.encode("utf-8")

if...break 会抛出包含 UL 的 LI,因为嵌套的 LI 现在是重复的。

现在的打印输出是:

102 斑点狗(2000) 10th & Wolf (2006) 11:14(2006) 12:08 布加勒斯特以东(2006) 13 继续 30(2004) 1408(2007) ...

【问题讨论】:

你问错问题了。您已经完成了问题标题中的内容,并且正在询问如何填写表格/对象/某物。请更新您的问题以反映这一点(并说明您所说的表格是什么意思 - 数据库表格或字典或其他内容,或者您​​不知道)。 我并不是想用最后一句话来混淆我的问题,所以我会澄清一下。现在我有一个带有子 的 列表,可能包含也可能不包含嵌套/子 (带有更多 )。我不确定如何提取所有的 lis。我将更改标题以更好地反映嵌套的 UL 问题。 【参考方案1】:
import requests
from bs4 import BeautifulSoup
r = requests.get("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_list_test")
soup =   BeautifulSoup(r.content,"lxml")
w3schollsList = soup.find_all('body')
for w3scholl in w3schollsList:
    ulList = w3scholl.find_all('li')
    for li in ulList:
        print(li)

注意:这里是获取我们制作的div里面的“li”

【讨论】:

【参考方案2】:

列表推导式也可以。

lis = [li for ul in uls for li in ul.findAll('li')]

【讨论】:

【参考方案3】:

.findAll() 适用于嵌套的 li 元素:

for ul in uls:
    for li in ul.findAll('li'):
        print(li)

输出:

<li>List items</li>
<li>Etc...</li>
<li>List items</li>
<li>Nested list items</li>
<li>Nested list items</li>
<li>List items</li>

【讨论】:

print(li.text) 将提取没有 html 的项目。

以上是关于BeautifulSoup:如何从包含一些嵌套 <ul> 的 <ul> 列表中提取所有 <li>?的主要内容,如果未能解决你的问题,请参考以下文章

beautifulSoup 不正确嵌套 <ul>s 的屏幕截图列表

如何仅使用BeautifulSoup和Python删除包含空格的HTML标记

在 Python 中使用 BS4 抓取数据,嵌套表

关于python中BeautifulSoup多层嵌套下标签内容寻找使用方法。

如何使用 BeautifulSoup 从父子标签中获取文本以放入 DOCX 表中

BeautifulSoup 嵌套标签