Belle soupe et extraction d'un div et de son contenu par ID

147
soup.find("tagName", { "id" : "articlebody" })

Pourquoi cela ne renvoie PAS les <div id="articlebody"> ... </div>balises et les éléments intermédiaires? Il ne renvoie rien. Et je sais pertinemment que ça existe parce que je le regarde depuis

soup.prettify()

soup.find("div", { "id" : "articlebody" }) ne fonctionne pas non plus.

( EDIT: j'ai trouvé que BeautifulSoup n'analysait pas correctement ma page, ce qui signifiait probablement que la page que j'essayais d'analyser n'est pas correctement formatée en SGML ou autre)

Tony Stark
la source
(Pour votre EDIT, cette question a toujours de la valeur en tant que ressource réutilisable pour les autres, même si l'analyseur ne fonctionne pas sur votre page particulière)
smci

Réponses:

202

Vous devez publier votre exemple de document, car le code fonctionne correctement:

>>> import BeautifulSoup
>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div id="articlebody"> ... </div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>

Trouver <div>s à l'intérieur de <div>s fonctionne également:

>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div><div id="articlebody"> ... </div></div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>
Lukáš Lalinský
la source
2
mon exemple de document est énorme. Je recherche le problème - je pense que cela ne fonctionne pas sur les divs des divs. J'ai compté le nombre de divs dans le document avec print len ​​(soupe ('div')) qui a abouti à 10, et je peux clairement voir plus de 10 divs avec firebug. donc je pense qu'il ne peut tout simplement pas trouver les divs dans les divs, donc j'ai besoin de restreindre les choses wrapper par wrapper.
Tony Stark
8
Eh bien, il est impossible de répondre à votre question, les boules de cristal ne sont pas un moyen fiable de débogage. :)
Lukáš Lalinský
1
J'ai essayé ce code. le div a <embed> et je ne peux pas imprimer l'intégration à l'intérieur.
Vincent
13
ou plus simplementdiv = soup.find(id="articlebody")
jfs
4
ousoup.find('div', id='articlebody')
Trevor Boyd Smith
71

Pour rechercher un élément par son id:

div = soup.find(id="articlebody")
jfs
la source
15

Beautiful Soup 4 prend en charge la plupart des sélecteurs CSS avec la .select()méthode , vous pouvez donc utiliser un idsélecteur tel que:

soup.select('#articlebody')

Si vous devez spécifier le type de l'élément, vous pouvez ajouter un sélecteur de type avant le idsélecteur:

soup.select('div#articlebody')

La .select()méthode retournera une collection d'éléments, ce qui signifie qu'elle renverra les mêmes résultats que l' exemple de .find_all()méthode suivant :

soup.find_all('div', id="articlebody")
# or
soup.find_all(id="articlebody")

Si vous ne souhaitez sélectionner qu'un seul élément, vous pouvez simplement utiliser la .find()méthode :

soup.find('div', id="articlebody")
# or
soup.find(id="articlebody")
Josh Crozier
la source
13

Je pense qu'il y a un problème lorsque les balises «div» sont trop imbriquées. J'essaie d'analyser certains contacts à partir d'un fichier html facebook, et Beautifulsoup ne parvient pas à trouver les balises "div" avec la classe "fcontent".

Cela se produit également avec d'autres classes. Quand je recherche des divs en général, cela ne tourne que ceux qui ne sont pas tellement imbriqués.

Le code source html peut être n'importe quelle page de Facebook de la liste d'amis d'un de vos amis (pas celle de vos amis). Si quelqu'un peut le tester et donner des conseils, je l'apprécierais vraiment.

Voici mon code, où j'essaye juste d'imprimer le nombre de balises "div" avec la classe "fcontent":

from BeautifulSoup import BeautifulSoup 
f = open('/Users/myUserName/Desktop/contacts.html')
soup = BeautifulSoup(f) 
list = soup.findAll('div', attrs={'class':'fcontent'})
print len(list)
omar
la source
9

Très probablement à cause de l'analyseur par défaut de beautifulsoup a un problème. Changez un analyseur différent, comme «lxml» et réessayez.

liang
la source
Cela a fonctionné pour moi, merci! J'ai utilisésoup = BeautifulSoup(data, parser="html.parser")
will-hart
8

Dans la source beautifulsoup, cette ligne permet aux div d'être imbriqués dans des divs; donc votre inquiétude dans le commentaire de Lukas ne serait pas valable.

NESTABLE_BLOCK_TAGS = ['blockquote', 'div', 'fieldset', 'ins', 'del']

Ce que je pense que vous devez faire est de spécifier les attrs que vous voulez, tels que

source.find('div', attrs={'id':'articlebody'})
dagoof
la source
5

avez-vous essayé soup.findAll("div", {"id": "articlebody"})?

cela semble fou, mais si vous récupérez des trucs de la nature, vous ne pouvez pas exclure plusieurs divs ...

utilisateur106514
la source
4

J'ai utilisé:

soup.findAll('tag', attrs={'attrname':"attrvalue"})

Comme ma syntaxe pour find / findall; Cela dit, à moins qu'il n'y ait d'autres paramètres optionnels entre la balise et la liste d'attributs, cela ne devrait pas être différent.


la source
4

Cela m'est arrivé aussi en essayant de gratter Google.
J'ai fini par utiliser pyquery.
Installer:

pip install pyquery

Utilisation:

from pyquery import PyQuery    
pq = PyQuery('<html><body><div id="articlebody"> ... </div></body></html')
tag = pq('div#articlebody')
Shoham
la source
3

Voici un fragment de code

soup = BeautifulSoup(:"index.html")
titleList = soup.findAll('title')
divList = soup.findAll('div', attrs={ "class" : "article story"})

Comme vous pouvez le voir, je trouve toutes les balises, puis je trouve toutes les balises avec class = "article" à l'intérieur

Récursion
la source
0

La Idpropriété est toujours identifiée de manière unique. Cela signifie que vous pouvez l'utiliser directement sans même spécifier l'élément. Par conséquent, c'est un plus si vos éléments le permettent d'analyser le contenu.

divEle = soup.find(id = "articlebody")
Iqra.
la source