Introducción a Python Scrapy
Que es Scrapy?
Scrapy (SKRAY-pee) es un Framework escrito en python para hacer web crawling y extraer datos estructurados los cuales pueden ser usados en un amplio rango de aplicaciones.
Scrapy en un principio fue diseñado para hacer web scraping pero actualmente puede ser usado para extraer datos usando API's o como un web crawler de propósito general
Web Crawling
Web crawling o web crawler algunas veces llamado spider, es un robot de internet(internet bot) usado típicamente para navegar en la WWW e indexar sitios.
Web Scraping
Es una tecnica en la cual un programa de computador extrae datos en formato comprensible para humanos y lo procesa, este lo realiza usando el protocolo HTTP o HTTPS
Instalación y Configuración
Scrapy esta escrito en Python y depende de unos pocos paquetes de Python entre otros:
- lxml, un eficiente XML y HTML parser
- parsel, una librería para la extracción de HTML/XML data
- w3lib, un helper multiproposito para lidiar con URLs y web encodings de paginas web
- twisted, framework de networking asincrono
-
cryptography y pyOpenSSL, para lidiar con varias necesidades de seguridad a nivel de redes
$ pip install Scrapy
Crear una spider para scrapear todos los artículos en las categorías de Electrical, Engineering Software y Wireless Modules & Adapters en http://uk.farnell.com/.
Deberá navegar por el árbol de categorías de productos (por ejemplo: Wireless Modules & Adapters / RF Modules / RF Power) hasta el nivel más bajo y analizarlo por producto.
Si un producto no tiene información para un campo en especifico omitir el campo.
EJERCICIO
Campos
- url: (string) Url del producto
- brand: (string) Marca del Producto
- title (string) Titulo que esta en el head
- unit_price: (float) Precio del producto
- tariff_number (string): Codigo del producto
- origin_country (string): País de origen
- primary_image_url: (string) URL de la imagen principal
- trail: (string list) Arreglos de
EJERCICIO
.
├── farnell
│ ├── __init__.py
│ ├── items.py # definición de los items
│ ├── middlewares.py # definición de los middleware
│ ├── pipelines.py # definición de los pipelines
│ ├── settings.py # archivo de configuración
│ └── spiders # aqui van a ir todos los spiders
│ ├── __init__.py
└── scrapy.cfg # archivo configuración del deploy
$ scrapy startproject farnell
SPIDER
- name: Todo spider debe tener un name asociado el cual se usara al momento de correrlo, este nombre es único dentro del proyecto.
- allowed_domains: Es una lista opcional de URL's con los dominios el los cuales al spider le esta permitido hacer el crawling.
- start_urls: Una lista de las URL's las cuales el spider iniciara a hacer crawling, las primeras paginas descargadas son las especificadas en esta lista.
- parse: Este es el default callback metodo usado por Scrapy para procesar los responses(respuestas), cuando los request no especifiquen un callback. Este metodo retorna un iterable de request y/o un dict de Items
import scrapy
class FarnellSpider(scrapy.Spider):
"""
Spider to crawl the URLS of the Electrical, Engineering Software,
and Wireless Modules & Adapters categories of http://uk.farnell.com/
"""
name = 'farnell'
start_urls = [
'http://uk.farnell.com/c/electrical',
'http://uk.farnell.com/c/engineering-software',
'http://uk.farnell.com/c/wireless-modules-adaptors'
]
def parse(self, response):
links = response.xpath('//nav[@class="filterCategoryLevelOne"]//a/@href').extract()
for url in links:
yield Request(url, callback=self.parse_subcategory, dont_filter=True)
...
SPIDER
SPIDER GENERICOS
Scrapy cuenta con los siguientes spiders genéricos:
-
CrawlSpider
-
XMLFeedSpider
-
CSVFeedSpider
-
SitemapSpider
mas información:
SELECTORES
La tarea mas comun que se realiza cuando se hace web scraping es la extracion de datos.
Scrapy cuenta con su propio mecanismo para la extracción de datos y se llaman selector(selectores) porque seleccionan ciertas partes de los documentos HTML especificadas ya sea por expresiones XPath o CSS.
XPath es un lenguaje para selección de nodos en XML el cual también puede ser usado en HTML.
SELECTORES
def parse(self, response):
# usando XPath
links = response.xpath('//nav[@class="filterCategoryLevelOne"]//a/@href').extract()
for url in links:
yield Request(url, callback=self.parse_subcategory, dont_filter=True)
def parse(self, response):
# usando XPath
links = response.css('nav[@class="filterCategoryLevelOne"]::a::attr(href)').extract()
for url in links:
yield Request(url, callback=self.parse_subcategory, dont_filter=True)
ITEMS
El principal objetivo de hacer web scraping es poder extrar datos estructurados de fuentes no estructuradas, tipicamente sitios o paginas web.
Para esto Scrapy nos provee con la Clase Item, el cual nos permite almacenar los datos. Esta Clase no es mas que una estructura de datos tipo Python Dict, donde podremos definir los campos disponibles.
import scrapy
class FarnellItem(scrapy.Item):
url = scrapy.Field()
brand = scrapy.Field()
title = scrapy.Field()
unit_price = scrapy.Field()
overview = scrapy.Field()
information = scrapy.Field()
manufacturer = scrapy.Field()
manufacturer_part = scrapy.Field()
tariff_number = scrapy.Field()
origin_country = scrapy.Field()
files = scrapy.Field()
file_urls = scrapy.Field()
image_urls = scrapy.Field()
primary_image_url = scrapy.Field()
trail = scrapy.Field()
ITEMS
ITEMS PIPELINES
Luego de que un item ha sido scrapeado por el spider es enviado al Pipeline el cual lo procesa en varios componentes que son ejecutados secuencialmente.
Los usos típicos de un Pipeline son
- Validar la data Scrapeada
- Chequear duplicados y elimiarlos
- Almacenar el Item scrapeado en una BD o escribirlo en un archivo.
ITEMS PIPELINES
import json
class FarnellPipeline(object):
def open_spider(self, spider):
self.file = open('products.jl', 'w')
def close_spider(self, spider):
self.file.close()
def process_item(self, item, spider):
line = json.dumps(dict(item)) + "\n"
self.file.write(line)
return item
Veamos Scrapy en Acción
scrapy
By Guillermo Alvarez
scrapy
- 748