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 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.
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
Scrapy esta escrito en Python y depende de unos pocos paquetes de Python entre otros:
$ 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
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
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
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