Un acercamiento al proceso de extracción y manipulación de datos con scrapy.
karen
Posted on August 9, 2022
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)
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()
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()}
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()
utilizando el jupyter notebook
importamos las librerias que utilizaremos que son: pandas y numpy
import numpy as np
import pandas as pd
leemos el csv y vemos los primeros 5 elementos con el metodo .head()
df = pd.read_csv("books.csv")
df.head()
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()
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")
Graficando
importamos el submodulo pyplot
import matplotlib.pyplot as plt
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})
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="--")
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()
si quieren pueden ver mi deepnote con el codigo de pandas y matplotlib Aqui el código
Posted on August 9, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.