web-dev-qa-db-fra.com

BeautifulSoup: Comment extraire tous les <li> s d'une liste de <ul> qui contient des <ul> imbriqués?

Mon code source ressemble à:

<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>

Je voudrais que toutes les balises "li" suivent la première balise "h3" et s'arrêtent à la prochaine balise "h2", y compris toutes les balises li imbriquées.

firstH3 = soup.find ('h3')

trouve correctement l'endroit où je voudrais commencer.

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

me donne une liste d'UL, chacun avec le contenu LI dont j'ai besoin.

EXTRAIT DE LA LISTE "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>

Mais je ne sais pas où aller d'ici. Je suis un programmeur débutant essayant de sauter dans Python en construisant un script qui gratte http://en.wikipedia.org/wiki/2000s_in_film et extrait un liste des "Titre du film (année)".


Mettre à jour:

Code final:

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")

La rupture If -> jette les LI qui contiennent des UL puisque les LI imbriqués sont maintenant dupliqués.

La sortie d'impression est maintenant:

  • 102 Dalmatiens (2000)
  • 10e et loup (2006)
  • 11:14 (2006)
  • 12h08 à l'est de Bucarest (2006)
  • 13 On continue le 30 (2004)
  • 1408 (2007)
  • ...

Merci

24
danneu

.findAll() fonctionne pour les éléments imbriqués li:

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

Production:

<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>
18
jfs

Une compréhension de la liste pourrait également fonctionner.

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