DEV Community

karen
karen

Posted on

Un acercamiento al proceso de extracción y manipulación de datos con scrapy.

Vision General

En este blog hare web scraping con un solo script utilizando scrapy y crawlerprocess, generando así un csv. Limpiaré los datos obtenidos y crearé una gráfica simple con ellos.

Haciendo el web scraping

Iniciamos la spider, vamos a escraperar el sitio books.toscrape.com

class BooksSpider(scrapy.Spider):
    name = "books_spider"
    def start_requests(self):
        yield scrapy.Request(url="http://books.toscrape.com/",callback=self.parse)
Enter fullscreen mode Exit fullscreen mode

Parseamos los datos de la página con xpath

    def parse(self, response):
        t = response.xpath('//article[@class="product_pod"]/h3/a/text()').extract()
        p = response.xpath('//article[@class = "product_pod"]/div[@class="product_price"]/p[@class="price_color"]/text()').extract()
        a = response.xpath('//article[@class = "product_pod"]/div[@class="product_price"]/p[contains(@class,"instock")]/text()').extract()
Enter fullscreen mode Exit fullscreen mode

A continuación una forma correcta de generar un csv, con un for recorrer las listas creadas en el paso anterior y hare una prelimpieza de estos datos con .strip() que eliminara los espacios restantes.

        for i in range(len(t)):
            yield {'title': t[i].strip(),'price': p[i].strip(),'availability': a[i].strip()}

Enter fullscreen mode Exit fullscreen mode

Generamos el csv

indicamos que el archivo de salida tendra el formato csv y se llamara books.csv


process = CrawlerProcess(settings={
    'FEED_FORMAT': 'csv',
    'FEED_URI': 'books.csv',
    'DOWNLOADER_MIDDLEWARES': {#esta configuracion es para user agents

'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
            'scrapy_user_agents.middlewares.RandomUserAgentMiddleware': 400,
        },

})
process.crawl(BooksSpider)
process.start()
Enter fullscreen mode Exit fullscreen mode

utilizando el jupyter notebook

importamos las librerias que utilizaremos que son: pandas y numpy

import numpy as np
import pandas as pd

Enter fullscreen mode Exit fullscreen mode

leemos el csv y vemos los primeros 5 elementos con el metodo .head()

df = pd.read_csv("books.csv") 
df.head()
Enter fullscreen mode Exit fullscreen mode

veemos que algunas filas no tiene todos sus datos asi que inspeccionamos el csv con .isna que nos devuelve true si faltan datos y tambien ponemos .any() para ver si faltan datos en cada columna

df.isna().any()
Enter fullscreen mode Exit fullscreen mode

solo faltan datos en availability que indica si hay o no stock, vamos a llenar los datos faltantes poniendo que no hay stock

df.fillna("Not in stock")
Enter fullscreen mode Exit fullscreen mode

Graficando

importamos el submodulo pyplot

import matplotlib.pyplot as plt
Enter fullscreen mode Exit fullscreen mode

Ahora queremos graficar el precio y la disponibilidad pero la columna "availability" es de tipo string asi que la mapearemos a valores numéricos indicando que si hay stock vale 1 y si no 0

df["cantidad_disponible"] = df["availability"].map({"In stock": 1,"Not in stock":0,np.nan:0})
Enter fullscreen mode Exit fullscreen mode

Generamos la grafica indicando que el precio estará en la abscisa x y la cantidad disponible en la abscisa, donde haya datos lo marcaremos con circulo "o", indicamos que la grafica sera de color azul con color = "b" y el estilo de la linea sera dasheado

fig, ax = plt.subplots()
ax.plot(df["price"],df["cantidad_disponible"],color="b",marker="o",linestyle="--")

Enter fullscreen mode Exit fullscreen mode

Ahora agregaremos labels y un título al gráfico

ax.set_xlabel("precio (en euros)")
ax.set_ylabel("disponibilidad")
ax.set_title("precio de libros")
plt.xticks(rotation=90)
plt.show() 
Enter fullscreen mode Exit fullscreen mode

si quieren pueden ver mi deepnote con el codigo de pandas y matplotlib Aqui el código

Top comments (0)