Scrapy: canalización de artículos
Descripción
Item Pipelinees un método en el que se procesan los artículos desechados. Cuando un artículo se envía a la canalización de artículos, una araña lo raspa y procesa utilizando varios componentes, que se ejecutan secuencialmente.
Siempre que se recibe un artículo, decide cualquiera de las siguientes acciones:
- Sigue procesando el artículo.
- Suéltelo de la tubería.
- Deje de procesar el artículo.
Las canalizaciones de artículos se utilizan generalmente para los siguientes propósitos:
- Almacenamiento de elementos raspados en la base de datos.
- Si se repite el elemento recibido, se eliminará el elemento repetido.
- Verificará si el artículo tiene campos específicos.
- Borrar datos HTML.
Sintaxis
Puede escribir la canalización de elementos utilizando el siguiente método:
process_item(self, item, spider)
El método anterior contiene los siguientes parámetros:
- Elemento (objeto de elemento o diccionario): especifica el elemento raspado.
- araña (objeto araña): la araña que raspó el objeto.
Puede utilizar métodos adicionales que se indican en la siguiente tabla:
No Señor | Método y descripción | Parámetros |
---|---|---|
1 | open_spider(self, spider) Se selecciona cuando se abre la araña. |
araña (objeto araña) - Se refiere a la araña que se abrió. |
2 | close_spider(self, spider) Se selecciona cuando la araña está cerrada. |
araña (objeto araña) - Se refiere a la araña que estaba cerrada. |
3 | from_crawler(cls, crawler) Con la ayuda del rastreador, la tubería puede acceder a los componentes centrales, como las señales y la configuración de Scrapy. |
crawler (objeto Crawler): se refiere al rastreador que utiliza esta canalización. |
Ejemplo
A continuación se muestran ejemplos de canalización de elementos utilizados en diferentes conceptos.
Soltar elementos sin etiqueta
En el siguiente código, la canalización equilibra el atributo (precio) para aquellos artículos que no incluyen IVA (atributo excludes_vat) e ignora aquellos artículos que no tienen etiqueta de precio -
from Scrapy.exceptions import DropItem
class PricePipeline(object):
vat = 2.25
def process_item(self, item, spider):
if item['price']:
if item['excludes_vat']:
item['price'] = item['price'] * self.vat
return item
else:
raise DropItem("Missing price in %s" % item)
Escribir elementos en un archivo JSON
El siguiente código almacenará todos los elementos raspados de todas las arañas en un solo items.jlarchivo, que contiene un elemento por línea en un formulario serializado en formato JSON. losJsonWriterPipeline la clase se usa en el código para mostrar cómo escribir la canalización de elementos -
import json
class JsonWriterPipeline(object):
def __init__(self):
self.file = open('items.jl', 'wb')
def process_item(self, item, spider):
line = json.dumps(dict(item)) + "\n"
self.file.write(line)
return item
Escribir elementos en MongoDB
Puede especificar la dirección de MongoDB y el nombre de la base de datos en la configuración de Scrapy y la colección de MongoDB puede tener el nombre de la clase de elemento. El siguiente código describe cómo utilizarfrom_crawler() método para recolectar los recursos adecuadamente -
import pymongo
class MongoPipeline(object):
collection_name = 'Scrapy_list'
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db
@classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri = crawler.settings.get('MONGO_URI'),
mongo_db = crawler.settings.get('MONGO_DB', 'lists')
)
def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]
def close_spider(self, spider):
self.client.close()
def process_item(self, item, spider):
self.db[self.collection_name].insert(dict(item))
return item
Filtros duplicados
Un filtro buscará los elementos repetidos y eliminará los elementos ya procesados. En el siguiente código, hemos utilizado una identificación única para nuestros artículos, pero spider devuelve muchos artículos con la misma identificación:
from scrapy.exceptions import DropItem
class DuplicatesPipeline(object):
def __init__(self):
self.ids_seen = set()
def process_item(self, item, spider):
if item['id'] in self.ids_seen:
raise DropItem("Repeated items found: %s" % item)
else:
self.ids_seen.add(item['id'])
return item
Activar una canalización de artículos
Puede activar un componente Item Pipeline agregando su clase a la configuración ITEM_PIPELINES como se muestra en el siguiente código. Puede asignar valores enteros a las clases en el orden en que se ejecutan (el orden puede ser de menor valor a clases de mayor valor) y los valores estarán en el rango de 0-1000.
ITEM_PIPELINES = {
'myproject.pipelines.PricePipeline': 100,
'myproject.pipelines.JsonWriterPipeline': 600,
}