55 votes

Beaufulsoup - nextSibling

J'essaie d'obtenir le contenu "My home address" en utilisant ce qui suit mais j'ai obtenu l'AttributeError :

address = soup.find(text="Address:")
print address.nextSibling

C'est mon HTML :

<td><b>Address:</b></td>
<td>My home address</td>

Quelle est une bonne façon de naviguer vers le bas td et en tirer le contenu ?

101voto

Henry Points 2992

Le problème est que vous avez trouvé un NavigableString et non le <td> . Aussi nextSibling trouvera le prochain NavigableString ou Tag donc même si vous aviez le <td> ça ne fonctionnerait pas comme vous le pensez.

C'est ce que vous voulez :

address = soup.find(text="Address:")
b_tag = address.parent
td_tag = b_tag.parent
next_td_tag = td_tag.findNext('td')
print next_td_tag.contents[0]

Ou plus concis :

print soup.find(text="Address:").parent.parent.findNext('td').contents[0]

En fait, vous pourriez simplement faire

print soup.find(text="Address:").findNext('td').contents[0]

Desde findNext juste des appels next encore et encore, et next trouve l'élément suivant comme analysé à plusieurs reprises jusqu'à ce qu'elle corresponde.

19voto

Vyachez Points 601

Essayez ceci si vous utilisez bs4 :

print soup.find(string="Address:").find_next('td').contents[0]

9voto

Stefan Falk Points 1224

Je ne sais pas si c'était possible en 2011, mais en 2021, je vous recommande de le faire en utilisant les éléments suivants find_next_sibling() comme ça :

address = soup.find(text="Address:")
b = address.parent
address_td = b.parent
target_td = address_td.find_next_sibling('td')

La réponse acceptée fonctionne dans votre cas mais elle ne fonctionnerait pas si vous aviez quelque chose comme :

<div>
  <div><b>Address:</b><div>THE PROBLEM</div></div>
  <div>target</div>
</div>

Vous vous retrouveriez avec <div>THE PROBLEM</div> au lieu de <div>target</div> .

3voto

zeekay Points 22640

Vous pouvez utiliser findChildren Il est assez facile d'itérer sur les td d'une table, en supposant qu'elle soit dans une table. L'idéal serait de trouver la table en premier :

table = soup.find('table')
>>> for td in table.findChildren('td'):
...:     print td.text
...:     
...:     
Address:
My home address

Ou vous pouvez rechercher l'adresse et obtenir le conteneur de table :

>>> import re
>>> search = re.compile('Address')
>>> table = soup.find(text=search).parent.parent.parent

0 votes

Il y a beaucoup de tables, donc trouver des tables puis td ne semble pas être un bon choix.

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