186 votes

Comment trouver les enfants des nœuds en utilisant BeautifulSoup

Je veux obtenir tous les <a> qui sont des enfants de <li> :

<div>
<li class="test">
    <a>link1</a>
    <ul> 
       <li>  
          <a>link2</a> 
       </li>
    </ul>
</li>
</div>

Je sais comment trouver un élément avec une classe particulière comme celle-ci :

soup.find("li", { "class" : "test" }) 

Mais je ne sais pas comment trouver tous les <a> qui sont des enfants de <li class=test> mais pas d'autres.

Comme je veux sélectionner :

<a>link1</a>

220voto

cerberos Points 2000

Essayez ceci

li = soup.find('li', {'class': 'text'})
children = li.findChildren("a" , recursive=False)
for child in children:
    print(child)

7 votes

Ou, pour simplement extraire l'expression qui décrit ce que nous voulons : soup.find('li', {'class': 'text'}).findChildren() .

8 votes

Mais comment obtenir la première balise <a> seulement et non après. quelque chose comme find(li).find(a).firstChild()

2 votes

Merci pour le kwarg "récursif" :)

150voto

freemasonjson Points 716

Il y a une toute petite section dans les DOCs qui montre comment trouver/trouver tous les direct les enfants.

https://www.crummy.com/software/BeautifulSoup/bs4/doc/#the-recursive-argument

Dans votre cas, vous voulez le lien 1 qui est le premier enfant direct :

# for only first direct child
soup.find("li", { "class" : "test" }).find("a", recursive=False)

Si vous voulez tous les enfants directs :

# for all direct children
soup.find("li", { "class" : "test" }).findAll("a", recursive=False)

24voto

Bemmu Points 5005

Peut-être que vous voulez faire

soup.find("li", { "class" : "test" }).find('a')

2 votes

Je pense qu'il trouvera <a> link2 </a> aussi bien mais je ne veux pas que

2 votes

Cela répond à la question de savoir comment sélectionner <a>link1</a> dans le HTML donné dans la question, mais cela échouera lorsque le premier <li class="test"> ne contiendra pas de <a> et il existe d'autres éléments li éléments avec test qui contient <a> .

0 votes

Cela ne répond pas à la question, mais c'est ce que je cherchais.

18voto

Jatimir Points 1547

"Comment trouver tous les a qui sont des enfants de <li class=test> mais pas d'autres ?"

Étant donné le HTML ci-dessous (j'ai ajouté un autre <a> pour montrer la différence entre select y select_one ):

<div>
  <li class="test">
    <a>link1</a>
    <ul>
      <li>
        <a>link2</a>
      </li>
    </ul>
    <a>link3</a>
  </li>
</div>

La solution consiste à utiliser combinateur d'enfants ( > ) qui est placé entre deux sélecteurs CSS :

>>> soup.select('li.test > a')
[<a>link1</a>, <a>link3</a>]

Dans le cas où vous voulez trouver seulement le premier enfant :

>>> soup.select_one('li.test > a')
<a>link1</a>

16voto

kiiru Points 191

Essayez ceci :

li = soup.find("li", { "class" : "test" })
children = li.find_all("a") # returns a list of all <a> children of li

d'autres rappels :

La méthode find ne récupère que le premier élément enfant apparu. La méthode find_all récupère tous les éléments descendants et les stocke dans une liste.

3 votes

Le demandeur ne veut aucune des deux options ci-dessus. Il veut tous les liens qui ne sont que des enfants directs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X