Web scraping con Python: guía paso a paso para principiantes

Last Updated on octubre 25, 2024 by Álvaro

El web scraping es de gran utilidad en diferentes disciplinas: análisis de datos, investigación de mercados, SEO… por lo que independientemente del ámbito al que pertenezcas, considero que no está de más aprender a cómo scrapear ya que te puede sacar de algún apuro en cualquier momento.

Aunque la programación suele asustar a muchos. déjame decirte que hacer web scraping con Python es más sencillo de lo que parece. Este tutorial va dirigido especialmente a principiantes, ya que se detallan incluso los pasos más sencillos. Se requieren los mínimos conocimientos de Python y HTML.

Portada tutorial web scraping en 5 minutos

Antes de nada: elige un entorno de desarrollo en el que te sientas cómodo

Si no tienes mucha experiencia, antes de lanzarte a entornos como Visual Studio Code, te recomiendo empezar por Jupyer Notebooks. Jupyter Notebooks es una especie de cuaderno en el que puedes crear varias celdas de código y acompañarlas de texto. Es muy útil para ejecutar pequeños fragmentos de código en el mismo documento y es muy usado en entornos profesionales para crear dashboards.

Guía paso a paso: Cómo hacer web scraping con Python desde 0

Para realizar el tutorial, yo procedería de la siguiente manera: reproduciría el vídeo que te de dejo por aquí abajo y lo seguiría junto a este artículo, ya que contiene todos los fragmentos de código que se utilizan y podrás copiarlos fácilmente.

El tutorial se realizará en base a un caso práctico. El objetivo es extraer todos los nombres y precios de los productos de la gama Botanical Collection de Lego, que se encuentran en la siguiente URL: https://www.lego.com/es-es/themes/adults-welcome/botanical-collection/artificial-flowers

Puedes descargar directamente el código clicando en el siguiente botón:

Paso 1: Instalación de las librerías

Es muy probable que no tengas instaladas las librerías que se necesitan. En este caso, estaremos trabajando con Beautiful Soup, Requests y Pandas.

Para instalarlas, simplemente ejecuta este código. *Este proceso solo tendrás que hacerlo la primera vez, una vez instaladas, no es necesario repetir esta operación*

pip install beautifulsoup4
pip install requests
pip install pandas

Paso 2: Importar las librerías

Una vez tengas instaladas las librerías, necesitarás importarlas. Este proceso lo tendrás que realizar cada vez que entres al documento de Jupyter Notebooks o a cualquier otro entorno de desarrollo.

En este caso, las estoy importando con alias (as + ‘abreviatura’). ¿Por qué? Ya que a la hora de escribir el código, habrá menos texto. Cuando necesites una función, por ejemplo, de Requests, en lugar de escribir ‘Requests’ al completo, bastará con especificar rq.

from bs4 import BeautifulSoup as bs
import requests as rq
import pandas as pd

Paso 3: lanzar una petición a la URL que queremos scrapear

Lo siguiente es lanzar una petición a la URL que queremos scrapear.

Es posible que este proceso sea algo lento (lento en términos de programación básica es que a lo mejor tarda 5-10 segundos).

response = rq.get('https://www.lego.com/es-es/themes/adults-welcome/botanical-collection/artificial-flowers')

*Al utilizar alias (as) en el import, en lugar de escribir request.get(‘…’) acortamos el código a rq.get(‘…’)*

Una vez finalice la petición (dejarás de ver [*] a la izquierda del código y en lugar de un asterisco aparecerá un número) podrás verificar si se ha realizado de manera correcta lanzando un print de response.

print(response)

Si la salida es Response [200], todo ha ido correctamente. Cualquier otra salida indicaría que ha habido un problema.

Paso 4: extraer el código HTML

Ahora necesitamos extraer el código HTML de la URL a la que lanzamos la petición.

soup = bs(response.text, 'html.parser')

La función BeautifulSoup (bs) tiene dos argumentos. El primero es el contenido de la respuesta HTTP. En otras palabras, el código HTML de la URL, que se obtiene ejecutando la propiedad .text en la variable en la que hemos guardado la petición (response). El segundo es el parser (analizador por así decirlo). Otros analizadores populares incluyen lxml y html5lib, que pueden ser más rápidos o manejar mejor ciertos casos de HTML mal formado.

Si lanzamos un print sobre soup, lo que obtenemos es todo el código HTML de la URL.

Salida por pantalla de la variable soup. En este caso, todo el código HTML
La salida de la variable soup es todo el código HTML

Paso 5: identificar como se representan los elementos que queremos scrapear en el HTML

Para saber qué etiqueta HTML y qué clase/atributo identifica al valor que queremos scrapear, situamos el cursor encima de este elemento > hacemos clic derecho > y hacemos clic izquierdo en inspeccionar. Esto abrirá la consola de desarrollo por la línea en la que se encuentra dicho valor.

En este caso, el objetivo es extraer tanto el nombre como el precio de los productos.

Ejemplo inspeccionando elemento
Ejemplo en el que inspecciono elemento

Para extraer el nombre tenemos la opción de hacerlo a través del <h3>, <a> o <span>, por tratarse de una secuencia de etiquetas anidadas. En este caso yo me he decantado por utilizar como referencia el anchor <a>. ¿Por qué? tiene elementos que identifican inequívocamente al nombre del producto, en este caso el atributo ‘data-test’ con valor ‘product-leaf-title’. Ten en cuenta que pueden existir valores que no nos interesa extraer que comparten etiquetas y clases o atributos con los que sí.

Elemento HTML en el que se guarda el valor que queremos scrapear
Elemento HTML en el que se guarda el valor que queremos scrapear

¿Y cómo sé si hay valores que no me interesan que comparten etiquetas y clase o atributos? Si en la consola de desarrollo hacemos ctrl + f, podemos buscar determinadas clases o atributos y comprobar cuántos elementos las tienen. En este caso vemos que el atributo ‘data-test’ con valor ‘product-leaf-title’ aparece 13 veces. Como tenemos solamente 13 productos, confirmamos que efectivamente ese atributo ubicado en las etiquetas <a> identifica inequívocamente a los productos.

ctrl+f para comprobar el atributo ubicado en las etiquetas <a> identifica inequívocamente a los productos

El precio, en cambio, se encuentra en un <div>. En este caso sí recurriremos a la etiqueta <span> para extraer el valor. Podríamos escoger de nuevo el atributo ‘data-test’, esta vez con valor ‘product-leaf-price’, pero para explicaros cómo se extrae un valor a partir de una clase, trabajaremos con la ‘class=”price-sm-bold”‘.

Elemento HTML en el que se guarda el valor que queremos scrapear
Elemento HTML en el que se guarda el valor que queremos scrapear

Resumen:

  • El nombre del producto está en una etiqueta <a> con atributo data-test=’product-leaf-price’.
  • El precio en una etiqueta <span> con clase class=”price-sm-bold”.

Paso 6: extraer los valores

El objetivo ahora es extraer las etiquetas que hemos identificado en el caso anterior. Para ello, nos ayudaremos de la función find_all(), que recibe dos argumentos. El primero, y que debe ir siempre en comillas, la etiqueta en la que se almacena el valor (‘a’, ‘div’, ‘span’, ‘h2’…) y el segundo el atributo o clase que lo acompaña e identifica.

Para los productos, nos estamos apoyando en un atributo:

buscar_productos = soup.find_all('a', attrs={'data-test': 'product-leaf-title'})

Y para los precios en una clase:

buscar_precios = soup.find_all('span', class_="price-sm-bold")

Como ves, el segundo argumento es distinto en cada caso. En el primero, los atributos se especifican dentro de attrs={} y se separa el nombre del valor con ‘:’.

Para las clases resulta más sencillo, ya que basta con simplemente copiar la clase tal cual del código HTML y añadirle a class un ‘_’ al final (esto se debe a que class es una palabra reservada en Python).

Si hacemos un print sobre cualquiera de estas variables, veremos que ahora tenemos una especie de lista que guarda todas las etiquetas. Fíjate que entre cada <a…>…</a> hay una coma. (Si nos ponemos estrictos esta variable no es realmente de tipo lista, aunque en la práctica esto no nos importa demasiado).

Salida que genera la variable buscar_productos
Salida que genera la variable buscar_productos

Ahora bien, necesitamos extraer, de una vez por todas, el valor que está dentro de estas etiquetas. Como en la práctica estas variables se comportan como una lista, las recorreremos con un ‘for’, extraeremos los valores y los guardaremos en una nueva lista con la función append().

Código para extraer los productos:

productos = []
for i in buscar_productos:
     productos.append(i.get_text())
        
print(productos)

Y su salida

valores de productos extraídos
valores de productos extraídos

Y para precios:

precios = []
for i in buscar_precios:
     precios.append(i.get_text())
        
print(precios)
valores de precios extraídos
valores de precios extraídos

Para extraer el valor nos estamos ayudando de la función get_text(), que ejecutamos sobre el elemento que itera ‘i’ (en este caso, cada una de las etiquetas).

Como ves, los valores de precios tienen caracteres que no nos interesan. En el siguiente paso los eliminaremos.

Paso 7: limpiar los valores (cuando sea pertinente)

Para limpiar los valores simplemente recorreremos la lista ‘precios’, eliminaremos los caracteres que no nos sirven y guardaremos el valor en una nueva lista.

Para eliminar los caracteres utilizaremos la función replace(), que necesita de dos argumentos. El primero, los caracteres que queremos sustituir/eliminar (entre comillas), y el segundo los caracteres por los que queremos sustituirlos. En este caso, como queremos eliminarlos, simplemente ponemos comillas simples sin nada dentro ”.

precios_limpios = []

for i in precios:
    precios_limpios.append(i.replace('\xa0', ''))

print(precios_limpios)
salida de la lista con los precios limpios
salida de la lista con los precios limpios

Paso 8: crear un data frame y exportarlo a Excel

En primer lugar, necesitamos crear un diccionario (una estructura de datos de Python) a partir de las dos listas que contienen los valores scrapeados. Para ello ejecutamos el siguiente código:

data = {
    "Productos": productos,
    "Precios": precios_limpios
}

Y el siguiente paso es convertir este diccionario en un data frame.

df = pd.DataFrame(data)

Finalmente, exportamos este marco de datos a un archivo xlsx con el siguiente código.

df.to_excel('output.xlsx', index=False)

¡Y listo! ya tenemos nuestros datos exportados a Excel. El archivo se guardará en la misma carpeta en la que tienes este proyecto de Python.

documento xslx con los valores scrapeados
documento xslx con los valores scrapeados

Ejemplos de web scraping en Python

El web scraping es muy útil para numerosas profesiones y en especial para los analistas de datos. Permite espiar a la competencia, crear marcos de datos a partir de elementos en la web…

Pero es también muy útil en otros ámbitos. Yo como SEO, he utilizado los siguientes algoritmos:

1 comentario en “Web scraping con Python: guía paso a paso para principiantes”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *