Sopa hermosa y extracción de un div y su contenido por ID

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

¿Por qué esto NO devuelve las <div id="articlebody"> ... </div>etiquetas y demás? No devuelve nada. Y sé a ciencia cierta que existe porque lo estoy mirando desde

soup.prettify()

soup.find("div", { "id" : "articlebody" }) Tampoco funciona.

( EDITAR: descubrí que BeautifulSoup no estaba analizando correctamente mi página, lo que probablemente significaba que la página que estaba tratando de analizar no estaba formateada correctamente en SGML o lo que sea)

Tony Stark
fuente
(Para su EDITAR, esta pregunta aún tiene valor como un recurso reutilizable para otros, incluso si el analizador no funciona en su página en particular)
smci

Respuestas:

202

Debe publicar su documento de ejemplo, porque el código funciona bien:

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

Encontrar <div>s dentro de <div>s también funciona:

>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div><div id="articlebody"> ... </div></div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>
Lukáš Lalinský
fuente
2
Mi documento de ejemplo es enorme. Estoy rastreando el problema, creo que esto no funciona en divs de divs. Hice un recuento de cuántos divs hay en el documento con print len ​​(soup ('div')) que resultó en 10, y puedo ver CLARAMENTE más de 10 divs con firebug. así que creo que simplemente no puede encontrar divs dentro de divs, así que necesito reducir las cosas envoltorio por envoltorio.
Tony Stark el
8
Bueno, entonces es imposible responder a su pregunta, las bolas de cristal no son una forma confiable de depuración. :)
Lukáš Lalinský
1
Probé este código. el div tiene <embed> y no puedo imprimir el embebido dentro de él.
Vincent
13
o más simplementediv = soup.find(id="articlebody")
jfs 05 de
44
osoup.find('div', id='articlebody')
Trevor Boyd Smith el
71

Para encontrar un elemento por su id:

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

Beautiful Soup 4 es compatible con la mayoría de los selectores CSS con el .select()método , por lo tanto, puede usar un idselector como:

soup.select('#articlebody')

Si necesita especificar el tipo de elemento, puede agregar un selector de tipo antes del idselector:

soup.select('div#articlebody')

los .select() método devolverá una colección de elementos, lo que significa que devolverá los mismos resultados que el siguiente ejemplo de .find_all()método :

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

Si solo desea seleccionar un solo elemento, puede usar el .find()método :

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

Creo que hay un problema cuando las etiquetas 'div' están demasiado anidadas. Estoy tratando de analizar algunos contactos de un archivo html de Facebook, y Beautifulsoup no puede encontrar las etiquetas "div" con la clase "fcontent".

Esto sucede con otras clases también. Cuando busco divs en general, solo se vuelven aquellos que no están tan anidados.

El código fuente html puede ser cualquier página de Facebook de la lista de amigos de un amigo tuyo (no el de tus amigos). Si alguien puede probarlo y dar algún consejo, realmente lo agradecería.

Este es mi código, donde solo trato de imprimir el número de etiquetas "div" con la clase "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
fuente
9

Lo más probable es que el analizador predeterminado de beautifulsoup tenga un problema. Cambie un analizador diferente, como 'lxml' e intente nuevamente.

liang
fuente
Esto funcionó para mí, gracias! Yo solíasoup = BeautifulSoup(data, parser="html.parser")
Will-Hart
8

En la fuente beautifulsoup, esta línea permite que los divs se aniden dentro de los divs; entonces su preocupación en el comentario de lukas no sería válida.

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

Lo que creo que debe hacer es especificar los atributos que desea, como

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

has intentado soup.findAll("div", {"id": "articlebody"})?

Suena loco, pero si estás sacando cosas de la naturaleza, no puedes descartar múltiples divs ...

usuario106514
fuente
4

Solía:

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

Como mi sintaxis para find / findall; Dicho esto, a menos que haya otros parámetros opcionales entre la etiqueta y la lista de atributos, esto no debería ser diferente.


fuente
4

Me pasó a mí también mientras intentaba raspar a Google.
Terminé usando pyquery.
Instalar en pc:

pip install pyquery

Utilizar:

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

Aquí hay un fragmento de código

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

Como puede ver, encuentro todas las etiquetas y luego encuentro todas las etiquetas con class = "article" dentro

Recursividad
fuente
0

La Idpropiedad siempre se identifica de forma única. Eso significa que puede usarlo directamente sin siquiera especificar el elemento. Por lo tanto, es un punto a favor si sus elementos tienen que analizar el contenido.

divEle = soup.find(id = "articlebody")
Iqra.
fuente