Web scraping con python

28-04-2024
web-scraping-con-python

¿Que es web scraping?

Es el proceso por el cual extraemos datos de paginas web utilizando scripts o bots que realizan requests y procesan los datos obtenidos

Contenido

Veamos juntos en este posteo la extracción de los datos de una pagina, el procesamiento de estos y grabar los mismos en 4 diferentes formatos de archivos:

  • Texto
  • CSV
  • JSON
  • Excel

Librerias

Vamos a necesitar tener instaladas las siguientes librerías:

  • beautifulsoup4
  • requests
  • openpyxl

Para esto en el directorio que contendrá nuestro codigo abrimos una terminal y ejecutamos los siguientes comandos.

Los comandos los estoy realizando en una terminal de powershell


python -m venv venv

.\venv\Scripts\activate

pip install requests beautifulsoup4 openpyxl

Fuente de datos

Para el ejemplo estoy utilizando los datos de una aplicación que cree para que puedan descargar y hackear 😉.

Cómo correr la aplicación se encuentra en el readme, les dejo el link app_for_web_scrapping

Codigo

Procesamiento de la página

La página de la cual vamos a obtener los datos contiene una tabla como esta:

Fecha Venta Compra
2023-01-02 346.0 342.0
2023-01-03 354.0 350.0
2023-01-04 354.0 350.0
2023-01-05 353.0 349.0

Primero obtengamos los datos de la página y procesamos los datos obtenidos con beautiful soup


import requests

from bs4 import BeautifulSoup

url = "http://localhost:3001/dollar-history"

page = requests.get(url)

soup = BeautifulSoup(str(page.content), 'html.parser')

table_data = []

for line in soup.find_all('tr'):
    header = line.find_all('th')
    data = line.find_all('td')
    if len(header) != 0:
        table_data.append([data.get_text() for data in header])
    if len(data) != 0:
        table_data.append([data.get_text().replace('$ ', '') for data in data])

url: esta variable alberga el string con la dirección de la página en la que se encuentran los datos.

page: contiene el objeto obtenido del request hecho con la librería requests.

soup: contiene el objeto de procesar el contenido BeautifulSoup requiere dos parámetros, el contenido de la página y el procesador a utilizar en este caso html.

table_data: va a contener una lista con cada linea de la tabla.

Si revisamos la página con el inspector nos encontramos con una tabla y la misma contiene para cada línea el tag tr, dentro de estos para el header de la tabla se utiliza th y para los datos td

tooltip

utilizando el método find_all(“tr”) obtenemos una lista con todas las lineas de la tabla.

luego recorremos con un for las lineas y en la misma buscamos si contiene el tag th o td para poder procesar el contenido del tag obtenido utilizando el metodo get_text() y agregamos la lista con el contenido de la tabla a table_data.

Con esto terminamos el procesamiento de la página y pasamos a trabajar los datos obtenidos.

Procesamiento de los datos

En el procesamiento de datos lo que se incluye en todas las solicitudes es grabar los mismos en algún tipo de archivo.

Las solicitudes en general son archivo csv, excel o json

Veamos cómo resolvemos esto con Python utilizando los datos que tenemos en table_data

CSV


# Escribir en un archivo csv

with open("export.csv", "w") as csv_file:
	# Formato en un string
    table_data_to_print = ""
    for line in table_data:
        for i in range(3):
                if i == 2:
                    table_data_to_print += f"{line[i]}\n"
                else:
                    table_data_to_print += f"{line[i]},"
    csv_file.write(table_data_to_print)

Lo mas sencillos es recorrer la lista table_data luego recorremos cada una de las listas que se encuentran en table_data y agregamos los datos como un string único en la variable table_data_to_print y al finalizar grabamos el archivo.

Si abrimos el archivo tendremos algo como lo siguiente:

Fecha,Venta,Compra

2023-01-02,346.0,342.0

2023-01-03,354.0,350.0

2023-01-04,354.0,350.0

JSON

Para grabar archivos json vamos a necesitar utilizar la librería json


# Escribir en un archivo json

import json

json_data = []

headers_for_json = []

for line in soup.find_all('tr'):
    headers = line.find_all('th')
    data = line.find_all('td')


    if len(headers) != 0:
        for header in headers:
            headers_for_json.append(header.get_text())
    if len(data) >= 1:
        obj = {}
        for i in range(3):
            obj[headers_for_json[i]] = data[i].get_text().replace('$ ', '')
        json_data.append(obj)
json_object = json.dumps(json_data, indent=4)

with open("export.json", "w") as json_file:
	json_file.write(json_object)

En este caso luego de importar la librería json tendremos que procesar de otra manera los datos obtenidos de la página como podemos ver se obtuvieron los datos lo que se cambia es que se agregan a la lista diccionarios en vez de listas.

Con json.dumps() se procesa la lista con los diccionarios y se crea la lista con los distintos objetos correspondientes al formato json y por últimos los grabamos en un archivo json

Si abrimos el archivo veremos algo como lo siguiente:

[

	{

    	"Fecha": "2023-01-02",

    	"Venta": "346.0",

    	"Compra": "342.0"

	},

	{

    	"Fecha": "2023-01-03",

    	"Venta": "354.0",

    	"Compra": "350.0"

	}

]

Excel

Cuando utilizamos excel tenemos que acudir al uso de ciertas librerías, una opción seria instalar pandas que incluye varias librerías entre ellas la que utilizo en este ejemplo openpyxl


from openpyxl import Workbook

import openpyxl

wb = Workbook()

ws = wb.active

for line_data in table_data:

	# Sabiendo los datos que se encuentran en la tabla podemos guardar los datos con el formato correcto

    if line_data[0] == "Fecha":
        ws.append(line_data)
    else:
        ws.append([ line_data[0], float(line_data[1]), float(line_data[2].replace('$ ','')) ])

wb.save("export.xlsx")

En este caso vemos cómo se procesan los datos que se encuentran en table_data de la misma forma y se van agregando los datos al sheet y por último son grabados en el excel

Conclusión

Vimos un breve procesamiento de los datos obtenidos de una página y como grabar los mismos en tres formatos distintos.

Recuerden revisar los distintos tags con el inspeccionador del explorador.