Scrapy - конвейер предметов
Описание
Item Pipeline- это метод обработки списанных предметов. Когда элемент отправляется в конвейер элементов, он очищается пауком и обрабатывается с использованием нескольких компонентов, которые выполняются последовательно.
Всякий раз, когда предмет получен, он решает одно из следующих действий:
- Продолжайте обрабатывать предмет.
- Бросьте его из трубопровода.
- Остановить обработку элемента.
Конвейеры предметов обычно используются для следующих целей:
- Хранение скребков в базе данных.
- Если полученный элемент повторяется, он отбрасывает повторяющийся элемент.
- Он проверит, есть ли у элемента целевые поля.
- Очистка данных HTML.
Синтаксис
Вы можете написать Item Pipeline, используя следующий метод -
process_item(self, item, spider)
Вышеупомянутый метод содержит следующие параметры -
- Item (объект-объект или словарь) - указывает очищенный элемент.
- паук (объект паука) - паук, который поцарапал предмет.
Вы можете использовать дополнительные методы, приведенные в следующей таблице -
Старший Нет | Метод и описание | Параметры |
---|---|---|
1 | open_spider(self, spider) Он выбирается при открытии паука. |
паук (объект паука) - относится к пауку, который был открыт. |
2 | close_spider(self, spider) Выбирается, когда паук закрыт. |
паук (объект паука) - относится к пауку, который был закрыт. |
3 | from_crawler(cls, crawler) С помощью краулера конвейер может получить доступ к основным компонентам, таким как сигналы и настройки Scrapy. |
краулер (объект краулера) - относится к краулеру, который использует этот конвейер. |
пример
Ниже приведены примеры конвейера элементов, используемых в различных концепциях.
Удаление предметов без тега
В следующем коде конвейер балансирует атрибут (цена) для тех товаров, которые не включают НДС (атрибут excludes_vat), и игнорирует те товары, которые не имеют ценника:
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)
Запись элементов в файл JSON
Следующий код сохранит все очищенные элементы от всех пауков в одном items.jlфайл, который содержит по одному элементу в строке в сериализованной форме в формате JSON. ВJsonWriterPipeline Класс используется в коде, чтобы показать, как писать конвейер элементов -
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
Запись элементов в MongoDB
Вы можете указать адрес MongoDB и имя базы данных в настройках Scrapy, а коллекция MongoDB может быть названа в честь класса элемента. Следующий код описывает, как использоватьfrom_crawler() способ правильно собрать ресурсы -
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
Дублирующие фильтры
Фильтр проверяет повторяющиеся элементы и отбрасывает уже обработанные элементы. В следующем коде мы использовали уникальный идентификатор для наших элементов, но паук возвращает много элементов с тем же идентификатором -
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
Активация конвейера предметов
Вы можете активировать компонент конвейера элементов, добавив его класс в параметр ITEM_PIPELINES, как показано в следующем коде. Вы можете присвоить целочисленные значения классам в том порядке, в котором они выполняются (порядок может иметь меньшее значение для классов с более высоким значением), и значения будут в диапазоне от 0 до 1000.
ITEM_PIPELINES = {
'myproject.pipelines.PricePipeline': 100,
'myproject.pipelines.JsonWriterPipeline': 600,
}