Tengo problemas para analizar elementos HTML con el atributo "class" usando Beautifulsoup. El código se ve así
soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs:
if (div["class"] == "stylelistrow"):
print div
Recibo un error en la misma línea "después" de que finaliza el script.
File "./beautifulcoding.py", line 130, in getlanguage
if (div["class"] == "stylelistrow"):
File "/usr/local/lib/python2.6/dist-packages/BeautifulSoup.py", line 599, in __getitem__
return self._getAttrMap()[key]
KeyError: 'class'
¿Cómo me deshago de este error?
<.. class="stylelistrow">
coincide pero no<.. class="stylelistrow button">
.class_
qué funciona correctamente.De la documentación:
A partir de Beautiful Soup 4.1.2, puede buscar por clase CSS utilizando el argumento de la palabra clave
class_
:Que en este caso sería:
También funcionaría para:
fuente
soup.find_all("a", ["stylelistrowone", "stylelistrow"])
es más seguro si no tienes muchas clases.soup.findAll("a", {'class':['stylelistrowone', 'stylelistrow']})
.Actualización: 2016 En la última versión de beautifulsoup, el método 'findAll' ha cambiado de nombre a 'find_all'. Enlace a documentación oficial
Por lo tanto, la respuesta será
fuente
Específico de BeautifulSoup 3:
Encontrará todo esto:
fuente
lambda x: 'stylelistrow' in x.split()
es simple y hermosoUna forma directa sería:
Asegúrese de quitar la carcasa de findAll , no es findall
fuente
<.. class="stylelistrow">
coincide pero no<.. class="stylelistrow button">
.Puede encontrar fácilmente por una clase, pero si desea encontrar por la intersección de dos clases, es un poco más difícil,
De la documentación (énfasis agregado):
Para que quede claro, esto selecciona solo las etiquetas p que son tachadas y de clase corporal.
Para buscar la intersección de cualquiera en un conjunto de clases (no la intersección, sino la unión), puede dar una lista al
class_
argumento de la palabra clave (a partir de 4.1.2):También tenga en cuenta que findAll ha cambiado de nombre de camelCase a Pythonic
find_all
.fuente
Selectores CSS
primer partido de una sola clase
lista de partidos
clase compuesta (es decir, Y otra clase)
Los espacios en los nombres de clase compuestos, por ejemplo,
class = stylelistrow otherclassname
se reemplazan con ".". Puedes continuar agregando clases.lista de clases (OR - coincide con el presente
bs4 4.7.1 +
Clase específica cuyo
innerText
contiene una cadenaClase específica que tiene un cierto elemento hijo, por ejemplo,
a
etiquetafuente
A partir de BeautifulSoup 4+,
Si tiene un solo nombre de clase, puede pasar el nombre de la clase como parámetro como:
O si tiene más de un nombre de clase, simplemente pase la lista de nombres de clase como parámetro como:
fuente
Intente verificar si el div tiene un atributo de clase primero, como este:
fuente
Esto funciona para mí para acceder al atributo de clase (en beautifulsoup 4, contrario a lo que dice la documentación). KeyError viene una lista que se devuelve, no un diccionario.
fuente
lo siguiente funcionó para mí
fuente
Esto funcionó para mí:
fuente
Alternativamente, podemos usar lxml, es compatible con xpath y muy rápido.
fuente
Esto debería funcionar:
fuente
Otras respuestas no me funcionaron.
En otras respuestas,
findAll
se está utilizando en el objeto de sopa en sí, pero necesitaba una forma de hacer una búsqueda por nombre de clase en objetos dentro de un elemento específico extraído del objeto que obtuve después de hacerlofindAll
.Si está intentando hacer una búsqueda dentro de elementos HTML anidados para obtener objetos por nombre de clase, intente a continuación:
Puntos a tener en cuenta:
No estoy definiendo explícitamente la búsqueda para que esté en el atributo 'clase'
findAll("li", {"class": "song_item"})
, ya que es el único atributo en el que estoy buscando y buscará de forma predeterminada el atributo de clase si no dice exclusivamente en qué atributo desea encontrar.Cuando haces un
findAll
ofind
, el objeto resultante es de clase,bs4.element.ResultSet
que es una subclase delist
. Puede utilizar todos los métodos deResultSet
, dentro de cualquier número de elementos anidados (siempre que sean de tipoResultSet
) para hacer una búsqueda o encontrar todos.Mi versión BS4 - 4.9.1, versión de Python - 3.8.1
fuente
Lo siguiente debería funcionar
reemplace 'totalcount' con el nombre de su clase y 'span' con la etiqueta que está buscando. Además, si su clase contiene varios nombres con espacio, simplemente elija uno y úselo.
PD Esto encuentra el primer elemento con criterios dados. Si desea encontrar todos los elementos, reemplace 'find' con 'find_all'.
fuente