Advertisement
  1. Code
  2. Python

Raspando Páginas Web en Python Con Beautiful Soup: Búsqueda y Modificación DOM

Scroll to top
Read Time: 8 min
This post is part of a series called Scraping Webpages in Python with Beautiful Soup.
Scraping Webpages in Python With Beautiful Soup: The Basics

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

En el último tutorial, aprendiste los básicos de la librería Beautiful Soup. Además de navegar el árbol DOM, también puedes buscar elementos de una class o id dados. También puedes modificar el árbol DOM usando esta librería.

En este tutorial, aprenderás sobre diferentes métodos que te ayudarán con la búsqueda y modificaciones. Estaremos raspando la misma página Wikipedia sobre Python del nuestro último tutorial.

Filtros Para Buscar el Árbol

Beautiful Soup tiene muchos métodos para buscar el árbol DOM. Estos métodos son muy similares y toman los mismos tipos de filtros como argumentos. Así pues, tiene sentido entender apropiadamente los distintos filtros antes de leer sobre los métodos. Estaré usando el mismo método find_all() para explicar la diferencia entre diferentes filtros.

El filtro más simple que puedes pasar a cualquier método de búsqueda es una cadena. Beautiful Soup entonces buscará a través del documento para encontrar una etiqueta que coincida exactamente con la cadena.

También puedes pasar un objeto de expresión regular al método find_all(). Esta vez, Beautiful Soup diltrará el árbol emparejando todas las etiquetas contra una expresión regular dada.

El código buscará todas las etiquetas que comiencen con "h" y son seguidas por un dígito de 1 a 6. En otras palabras, estará buscando todas las etiquetas de encabezado en el documento.

En vez de usar regex, podrías archivar el mismo resultado pasando una lista de todas las etiquetas que quieras que Beautiful Soup compare con el documento.

También puedes pasar True como parámetro del método find_all(). El código entonces devolverá todas las etiquetas en el documento. La salida de abajo significa que hay actualmente 4,399 etiquetas en la página de  Wikipedia que estamos analizando.

Si aún no puedes encontrar lo que estás buscando con cualquiera de los filtros de arriba, puedes definir tu propia función que toma un elemento como su único argumento. La función también necesita regresar True si hay una coincidencia y False de otro modo. Dependiendo de lo que necesites, puedes hacer la función tan complicada como sea necesario para hacer el trabajo. Aquí está un ejemplo muy simple.

La función de arriba va a recorrer la misma página Python de Wikipedia y buscar listas sin orden que tengan más de 20 hijos.

Buscando el Árbol DOM Usando Funciones Integradas

Uno de los métodos más populares para buscar a través del DOM es find_all(). Recorrerá todos los descendientes de etiquetas para empatar tu criterio de búsqueda. Este método tiene la siguiente firma:

El argumento name es el nombre de la etiqueta que quieres que busque esta función mientras recorre el árbol. Eres libre de proporcionar una cadena, una lista, una expresión regular, una función, o el valor True como nombre.

También puedes filtrar los elementos en el árbol DOM en la base de diferentes atributos como id, href, etc. También puedes obtener todos los elementos con un atributo específico independientemente de su valor usando attribute=True. Buscar elementos con una clase específica es diferente de buscar atributos regulares. Ya que class es una palabra clave reservada en Python, tendrás que usar el argumento de palabra clave class_ cuando busques elementos con una clase específica.

Puedes ver que el documento tiene 1,734 etiquetas con un atributo class y 425 etiquetas con un atributo id. Si solo necesitas el primero de estos resultados, puedes pasar un número al método como el valor de limit. Pasar este valor instruirá a Beautiful Soup que deje e buscar más elementos una vez que ha alcanzado cierto número. Aquí está un ejemplo:

Cuando usas el método find_all(), le estás diciendo a Beautiful Soup que vaya a través de todos los descendientes de una etiqueta dada para encontrar lo que estás buscando. Algunas veces, quieres buscar un elemento solo en el hijo directo en una etiqueta. Esto puede ser logrado pasando recursive=False al método find_all().

Si estás interesado en encontrar solo un resultado para una consulta de búsqueda particular, puedes usar el método find() para encontrarlo en vez de pasar limit=1 a find_all(). La única diferencia entre los resultados devueltos por estos dos métodos es que find_all() devuelve una lista con solo un elemento y find() solo devuelve el resultado.

Los métodos find() y find_all() buscan a través de todos los descendientes de una etiqueta dada para un elemento. Hay otros diez métodos muy similares que puedes usar para iterar a través del árbol DOM en diferentes direcciones.

Los métodos find_parent() y find_parents() atraviesan el árbol DOM para encontrar el elemento dado. Los métodos find_next_sibling() y find_next_siblings() iterarán sobre todos los hermanos del elemento que viene después del actual. De manera similar, los métodos find_previous_sibling() y find_previous_siblings() iterarán sobre todos los hermanos del elemento que viene antes del actual.

Los métodos find_next() y find_all_next() iterarán sobre todas las etiquetas y cadenas que vienen después del elemento actual. De manera similar, los métodos find_previous() y find_all_previous() iterarán sobre todas las etiquetas y cadenas que vienen antes del elemento actual.

También puedes buscar elementos usando selectores CSS con la ayuda del método select(). Aquí hay unos cuántos ejemplos.

Modificando el Árbol

No solo puedes buscar a través del árbol DOM para encontrar un elemento sino también modificarlo. Es muy sencillo renombrar una etiqueta y modificar sus atributos.

Continuando desde nuestro último ejemplo, puedes reemplazar los contenidos de una etiqueta con una cadena dada usando el atributo .string. Si no quieres reemplazar los contenidos sino agregar algo extra al final de la etiqueta, puedes usar el método append().

De manera similar, si quieres insertar algo dentro de una etiqueta en una ubicación específica, puedes usar el método insert(). El primer parámetro para este método es la posición o índice en el cuál quieres insertar el contenido, y el segundo parámetro es el contenido mismo. Puedes remover todo el contenido dentro de una etiqueta usando el método clear(). Esto solo te dejará con la etiqueta misma y sus atributos.

Al inicio de esta sección, seleccionaste un encabezado de nivel dos del documento y lo cambiaste a encabezado de nivel tres. Usar el mismo selector otra vez, ahora te muestra el siguiente encabezado 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 puede ahora ser seleccionado usando h3:nth-of-type(2). Si quieres remover completamente un elemento o etiqueta y todo el contenido dentro de esta del árbol, puedes usar el método decompose().

Una vez que has descompuesto o removido el encabezado original, el encabezado en el tercer espacio toma su lugar.

Si quieres remover una etiqueta y sus contenidos del árbol pero no quieres destruir la etiqueta por completo, puedes usar el método extract(). 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 recién extrajiste.

También puedes reemplazar una etiqueta dentro del árbol con algo más de tu elección usando el método replace_with(). Este método devolverá la etiqueta o cadena que reemplazó. Puede ser de utilidad si quieres colocar el contenido reemplazado en algún otro lugar en el documento.

En el código de arriba, el encabezado principal del documento ha sido reemplazado con una etiqueta b. El documento ya no tiene una etiqueta h1 y es por eso que print(soup.h1) imprime None.

Ideas Finales

Después de leer los dos tutoriales en la serie, deberías ahora poder analizar diferentes páginas web y extraer datos importantes desde el documento. Deberías también poder traer la página web original, modificándola para satisfacer tus propias necesidades, y guardar la versión modificada de manera local.

Si tienes alguna pregunta en referencia a este tutorial, por favor déjame saber en los comentarios.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.