En el último tutorial, aprendiste los conceptos básicos de la biblioteca Beautiful Soup. Además de navegar por el árbol DOM, también puede buscar elementos con un determinado clase
o carné de identidad
. También puede modificar el árbol DOM usando esta biblioteca.
En este tutorial, aprenderá sobre los diferentes métodos que lo ayudarán con la búsqueda y las modificaciones. Estaremos raspando la misma página de Wikipedia sobre Python de nuestro último tutorial.
Beautiful Soup tiene muchos métodos para buscar en el árbol DOM. Estos métodos son muy similares y toman los mismos tipos de filtros que los argumentos. Por lo tanto, tiene sentido entender correctamente los diferentes filtros antes de leer sobre los métodos. Yo estare usando el mismo encuentra todos()
Método para explicar la diferencia entre diferentes filtros..
El filtro más simple que puede pasar a cualquier método de búsqueda es una cadena. Beautiful Soup buscará en el documento para encontrar una etiqueta que coincida exactamente con la cadena.
para encabezar en soup.find_all ('h2'): print (heading.text) # Contenido # Historia [editar] # Características y filosofía [editar] # Sintaxis y semántica [editar] # Bibliotecas [editar] # Entornos de desarrollo [editar] #… y así.
También puede pasar un objeto de expresión regular a la encuentra todos()
método. Esta vez, Beautiful Soup filtrará el árbol al comparar todas las etiquetas con una expresión regular dada.
importar para el encabezado en soup.find_all (re.compile ("^ h [1-6]")): print (heading.name + "+ heading.text.strip ()) # h1 Python (lenguaje de programación) # h2 Contenido # h2 Historial [editar] # h2 Características y filosofía [editar] # h2 Sintaxis y semántica [editar] # h3 Indentación [editar] # h3 Declaraciones y flujo de control [editar] #… y así sucesivamente.
El código buscará todas las etiquetas que comienzan con "h" y van seguidas de un dígito del 1 al 6. En otras palabras, buscará todas las etiquetas de encabezado en el documento.
En lugar de usar expresiones regulares, puede obtener el mismo resultado al pasar una lista de todas las etiquetas que desea que Beautiful Soup haga coincidir con el documento.
para el encabezado en soup.find_all (["h1", "h2", "h3", "h4", "h5", "h6"]): print (heading.name + "+ heading.text.strip ())
También puedes pasar Cierto
como parámetro a la encuentra todos()
método. El código devolverá todas las etiquetas en el documento. El resultado a continuación significa que actualmente hay 4,339 etiquetas en la página de Wikipedia que estamos analizando.
len (soup.find_all (Verdadero)) # 4339
Si aún no puede encontrar lo que está buscando con cualquiera de los filtros anteriores, puede definir su propia función que toma un elemento como único argumento. La función también necesita volver. Cierto
si hay un partido y Falso
de otra manera. Dependiendo de lo que necesite, puede hacer que la función sea tan complicada como debe ser para hacer el trabajo. Aquí hay un ejemplo muy simple:
def big_lists (tag): return len (tag.contents)> 20 y tag.name == 'ul' len (soup.find_all (big_lists)) # 13
La función anterior pasa por la misma página de Wikipedia Python y busca listas desordenadas que tienen más de 20 niños.
Uno de los métodos más populares para buscar a través del DOM es encuentra todos()
. Pasará por todos los descendientes de la etiqueta y devolverá una lista de todos los descendientes que coincidan con sus criterios de búsqueda. Este método tiene la siguiente firma:
find_all (nombre, attrs, recursivo, cadena, límite, ** kwargs)
los nombre
argumento es el nombre de la etiqueta que desea que esta función busque mientras atraviesa el árbol. Tiene la libertad de proporcionar una cadena, una lista, una expresión regular, una función o el valor Cierto
como un nombre.
También puede filtrar los elementos en el árbol DOM en base a diferentes atributos como carné de identidad
, href
, etc. También puede obtener todos los elementos con un atributo específico independientemente de su valor usando atributo = Verdadero
. La búsqueda de elementos con una clase específica es diferente de la búsqueda de atributos regulares. Ya que clase
es una palabra clave reservada en Python, tendrá que usar el clase_
argumento de palabra clave cuando se buscan elementos con una clase específica.
import re len (soup.find_all (id = True)) # 425 len (soup.find_all (class_ = True)) # 1734 len (soup.find_all (class _ = "mw-headline")) # 20 len (soup.find_all (href = Verdadero)) # 1410 len (soup.find_all (href = re.compile ("python"))) # 102
Puedes ver que el documento tiene 1,734 tags con un clase
atributo y 425 etiquetas con una carné de identidad
atributo. Si solo necesita los primeros resultados, puede pasar un número al método como el valor de límite
. Pasar este valor indicará a Beautiful Soup que deje de buscar más elementos una vez que haya alcanzado un cierto número. Aquí hay un ejemplo:
soup.find_all (class _ = "mw-headline", limit = 4) # Historia # Caracteristicas y filosofia # Sintaxis y semantica # Sangría
Cuando usas el encuentra todos()
Método, le está diciendo a Beautiful Soup que pase por todos los descendientes de una etiqueta determinada para encontrar lo que está buscando. A veces, desea buscar un elemento solo en los hijos directos de una etiqueta. Esto se puede lograr pasando recursivo = falso
al encuentra todos()
método.
len (soup.html.find_all ("meta")) # 6 len (soup.html.find_all ("meta", recursive = False)) # 0 len (soup.head.find_all ("meta", recursive = False) ) # 6
Si está interesado en encontrar solo un resultado para una consulta de búsqueda en particular, puede usar el encontrar()
Método para encontrarlo en lugar de pasar. límite = 1
a encuentra todos()
. La única diferencia entre los resultados devueltos por estos dos métodos es que encuentra todos()
devuelve una lista con un solo elemento y encontrar()
solo devuelve el resultado.
soup.find_all ("h2", limit = 1) # [Contenido
] soup.find ("h2") #Contenido
los encontrar()
y encuentra todos()
Los métodos buscan a través de todos los descendientes de una etiqueta dada para buscar un elemento. Hay otros diez métodos muy similares que puede utilizar para recorrer en iteración el árbol DOM en diferentes direcciones..
find_parents (name, attrs, string, limit, ** kwargs) find_parent (name, attrs, string, ** kwargs) find_next_siblings (name, attrs, string, limit, ** kwargs) find_next_sibling (name, attrs, string, ** kwargs) find_previous_siblings (name, attrs, string, limit, ** kwargs) find_previous_sibling (name, attrs, string, ** kwargs) find_all_next (name, attrs, string, limit, ** kwargs) find_next (name, attrs, string, ** kwargs) find_all_previous (nombre, attrs, cadena, límite, ** kwargs) find_previous (nombre, attrs, cadena, ** kwargs)
los buscar_parente ()
y buscar_parentes ()
Los métodos atraviesan el árbol DOM para encontrar el elemento dado. los find_next_sibling ()
y find_next_siblings ()
Los métodos iterarán sobre todos los hermanos del elemento que vienen después del actual. Del mismo modo, el find_previous_sibling ()
y find_previous_siblings ()
Los métodos iterarán sobre todos los hermanos del elemento que precede al actual..
los buscar_next ()
y find_all_next ()
los métodos iterarán sobre todas las etiquetas y cadenas que vienen después del elemento actual. Del mismo modo, el find_previous ()
y find_all_previous ()
los métodos iterarán sobre todas las etiquetas y cadenas que vienen antes del elemento actual.
También puede buscar elementos utilizando los selectores de CSS con la ayuda de seleccionar()
método. Aquí están algunos ejemplos:
len (soup.select ("p a")) # 411 len (soup.select ("p> a")) # 291 soup.select ("h2: nth-of-type (1)") # [Contenido
] len (soup.select ("p> a: nth-of-type (2)")) # 46 len (soup.select ("p> a: nth-of-type (10)")) # 6 len (soup.select ("[class * = section]")) # 80 len (soup.select ("[class $ = section]")) # 20
No solo puede buscar a través del árbol DOM para encontrar un elemento, sino también modificarlo. Es muy fácil cambiar el nombre de una etiqueta y modificar sus atributos.
heading_tag = soup.select ("h2: nth-of-type (2)") [0] heading_tag.name = "h3" print (heading_tag) #Feat ... heading_tag ['class'] = 'headingChanged' print (heading_tag) #
Continuando con nuestro último ejemplo, puede reemplazar el contenido de una etiqueta con una cadena dada usando la
.cuerda
atributo. Si no desea reemplazar el contenido pero agrega algo adicional al final de la etiqueta, puede usar laadjuntar()
método.Del mismo modo, si desea insertar algo dentro de una etiqueta en una ubicación específica, puede usar la
insertar()
método. El primer parámetro para este método es la posición o el índice en el que desea insertar el contenido, y el segundo parámetro es el contenido en sí. Puede eliminar todo el contenido dentro de una etiqueta usando laclaro()
método. Esto te dejará con la etiqueta y sus atributos..heading_tag.string = Impresión de "Características y Filosofía" (heading_tag) #Características y filosofía
heading_tag.append ("[Adjunto esta parte].") print (heading_tag) #Características y filosofía [adjunto esta parte].
print (heading_tag.contents) # ['Features and Philosophy', '[Addended This Part].'] heading_tag.insert (1, 'Inserts this part') print (heading_tag) #Características y filosofía Insertó esta parte [Se adjunta esta parte].
heading_tag.clear () imprimir (heading_tag) #Al comienzo de esta sección, seleccionó un encabezado de nivel dos del documento y lo cambió a un encabezado de nivel tres. Volver a usar el mismo selector ahora le mostrará el siguiente encabezado de nivel dos que vino después del original. Esto tiene sentido porque el encabezado original ya no es un encabezado de nivel dos.
El encabezado original ahora se puede seleccionar usando
h3: nth-of-type (2)
. Si desea eliminar por completo un elemento o etiqueta y todo el contenido que contiene dentro del árbol, puede usardescomponer()
método.soup.select ("h3: nth-of-type (2)") [0] # soup.select ("h3: nth-of-type (3)") [0] #Sangría... soup.select ("h3: nth-of-type (2)") [0] .decompose () soup.select ("h3: nth-of-type (2)") [0] #
Sangría...
Una vez que haya descompuesto o quitado el encabezado original, el encabezado en el tercer lugar toma su lugar..
Si desea eliminar una etiqueta y su contenido del árbol, pero no quiere destruirla por completo, puede usar la
extraer()
método. Este método devolverá la etiqueta que extrajo. Ahora tendrás dos árboles diferentes que puedes analizar. La raíz del nuevo árbol será la etiqueta que acaba de extraer..heading_tree = soup.select ("h3: nth-of-type (2)") [0] .extract () len (heading_tree.contents) # 2También puede reemplazar una etiqueta dentro del árbol con otra cosa de su elección usando el
reemplazar con()
método. Este método devolverá la etiqueta o cadena que reemplazó. Puede ser útil si desea colocar el contenido reemplazado en otro lugar del documento..soup.h1 #Python (lenguaje de programación)
bold_tag = soup.new_tag ("b") bold_tag.string = "Python" soup.h1.replace_with (bold_tag) print (soup.h1) # Ninguno print (soup.b) # PitónEn el código anterior, el encabezado principal del documento ha sido reemplazado por un
segundo
etiqueta. El documento ya no tiene unah1
etiqueta, y es por esoimprimir (soup.h1)
ahora imprimeNinguna
.Pensamientos finales
Después de leer los dos tutoriales de esta serie, ahora debería poder analizar diferentes páginas web y extraer datos importantes del documento. También debe poder recuperar la página web original, modificarla para que se ajuste a sus propias necesidades y guardar la versión modificada localmente.
Si tiene alguna pregunta sobre este tutorial, hágamelo saber en los comentarios..