2009-08-07 20 views
37

si una página tiene <div class="class1"> y <p class="class1">, entonces soup.findAll(True, 'class1') las encontrará. Sin embargo, si no tiene <p class="class1 class2">, no se encontrará. ¿Cómo encuentro todos los objetos con una cierta clase, independientemente de si también tienen otras clases?Beautiful Soup no puede encontrar una clase CSS si el objeto tiene otras clases, también

+3

** ** Actualización: Esta informes, se ha fijado en el 4 beta 5: https://bugs.launchpad.net/beautifulsoup/+bug/410304 – endolith

Respuesta

15

Por si acaso alguien se encuentra con esta pregunta. BeautifulSoup ahora es compatible con esto:

Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] 
Type "copyright", "credits" or "license" for more information. 

In [1]: import bs4 

In [2]: soup = bs4.BeautifulSoup('<div class="foo bar"></div>') 

In [3]: soup(attrs={'class': 'bar'}) 
Out[3]: [<div class="foo bar"></div>] 

Además, usted no tiene que escribir findAll más.

34

Desafortunadamente, BeautifulSoup lo trata como una clase con un espacio en él 'class1 class2' en lugar de dos clases ['class1','class2']. Una solución alternativa es usar una expresión regular para buscar la clase en lugar de una cadena.

Esto funciona:

soup.findAll(True, {'class': re.compile(r'\bclass1\b')}) 
+2

https://bugs.launchpad.net/bugs/410304 – endolith

+3

Esto parece estar arreglado ahora. – Kugel

+1

@Kugel: agregue otra respuesta, entonces? – endolith

10

Debe utilizar lxml. Funciona con múltiples valores de clase separados por espacios ('class1 class2').

A pesar de su nombre, lxml también es para analizar y raspar HTML. Es mucho, mucho más rápido que BeautifulSoup, e incluso maneja HTML "roto" mejor que BeautifulSoup (su reclamo de fama). También tiene una API de compatibilidad para BeautifulSoup si no desea aprender la API lxml.

Ian Bicking agrees y prefiere lxml en BeautifulSoup.

No hay ninguna razón para usar BeautifulSoup, a menos que esté en Google App Engine o algo en que no esté permitido nada que no sea puramente Python.

Incluso puede usar selectores de CSS con lxml, por lo que es mucho más fácil de usar que BeautifulSoup. Intenta jugar con él en una consola interactiva de Python.

+7

De la propia documentación de lxml: "Mientras que libxml2 (y por lo tanto lxml) también puede analizar HTML fragmentado, BeautifulSoup es un poco más indulgente y tiene soporte adicional para la detección de codificación". – endolith

+0

Lo he probado y de hecho es más agradable para este tipo de cosas. – endolith

+0

Me alegro de que te guste. Espero que también corra la voz, lxml es una biblioteca poco apreciada. Creo que muchos lo pasan por alto ya que tiene 'XML' en el nombre y su documentación no es tan buena como la de BeautifulSoup. BS tiene un encanto con el nombre y los gráficos, lo que lo hace un poco más atractivo por razones superficiales. – aehlke

2

Es muy útil buscar una etiqueta que tenga una cierta clase de CSS, pero el nombre del atributo CSS, "clase", es una palabra reservada en Python. Usar la clase como un argumento de palabra clave le dará un error de sintaxis. A partir de Hermosa sopa 4.1.2, se puede buscar por clase CSS con el argumento de palabra clave class_:

igual:

soup.find_all("a", class_="class1") 
+0

Lo siento, pero creo que su respuesta es incorrecta. De acuerdo con el documento Beautiful Soup (http://www.crummy.com/software/BeautifulSoup/bs3/documentation.html#Searching%20by%20CSS%20class), hay dos opciones para usar 'find_all' para encontrar una etiqueta con un Clase CSS: pasa el nombre de la clase como una cadena o crea una dicción con la clave "clase" y un valor con el nombre de la clase CSS. –

+0

Me alegra ver mi respuesta, pero estoy usando bs4, no bs3, tal vez la interfaz ha cambiado @ RodrigoTaboada –

+0

De acuerdo con el documento Beautiful Soup4 [link] (http://www.crummy.com/software/BeautifulSoup/bs4/ doc/# searching-by-css-class) –

Cuestiones relacionadas