Как я могу заставить паука Scrapy работать с несколькими конвейерами? - PullRequest
0 голосов
/ 27 июня 2018

У меня есть проект Scrapy, который извлекает данные с сайта и загружает эти данные в несколько таблиц в базе данных PostreSQL. Ниже приведена упрощенная версия моего кода:

Мой файл pipelines.py:

class PoliticiansPipeline(object):
    def open_spider(self, spider): #opens the database connection
    def close_spider(self, spider): #closes the database connection
    def process_item(self, item, spider): #pulls data from item and uploads it to database

class HouseMembersPipeline(object):
    def open_spider(self, spider): #opens the database connection
    def close_spider(self, spider): #closes the database connection
    def process_item(self, item, spider): #pulls data from item and uploads it to database

И из моего файла settings.py:

ITEM_PIPELINES = {
    'house_members.pipelines.PoliticiansPipeline': 100,
    'house_members.pipelines.HouseMembersPipeline': 200,
}

Но каждый раз, когда я запускаю скрипт в командной строке, он возвращает ошибку "TypeError: 'NoneType' object is not subscriptable". Я запустил каждый конвейер отдельно, и они работают без ошибок. Я также объединил оба конвейера в один большой конвейер, и это тоже работает. Но когда я разделяю его на несколько конвейеров, он перестает работать.

Мне не удалось найти каких-либо реальных примеров, показывающих это, и документация Scrapy явно не детализировала, как обрабатывать несколько конвейеров. У кого-нибудь есть примеры работы конвейера или ресурс, который я могу использовать для устранения неполадок? Любая помощь приветствуется!

РЕДАКТИРОВАТЬ: ниже трассировки стека ошибки:

2018-06-26 23:27:11 [scrapy.core.scraper] 
ERROR: Error processing {'first_name': 'Mike', 'last_name': 'Gallagher', 'party': 'R', 'state': 'WI', 'district': '8th'}
Traceback (most recent call last):
File "C:\Users\cmatt\Anaconda3\lib\site-packages\twisted\internet\defer.py", line 653, in _runCallbacks
  current.result = callback(current.result, *args, **kw)
File "C:\Users\cmatt\eclipse-workspace\house_members\house_members\pipelines.py", line 92, in process_item
  new_tuple = (item['first_name'], item['last_name'], item['party'], item['state'])
TypeError: 'NoneType' object is not subscriptable

1 Ответ

0 голосов
/ 28 июня 2018

Когда вы определяете свои конвейеры, как показано ниже

ITEM_PIPELINES = {
    'house_members.pipelines.PoliticiansPipeline': 100,
    'house_members.pipelines.HouseMembersPipeline': 200,
}

PoliticiansPipeline будет вызываться первым, а HouseMembersPipeline позже. Первый конвейер может изменить элемент и вернуть его, или он может отбросить элемент все вместе. Чтобы бросить вы можете сделать

raise DropItem("Item already in DB")

Сделав это, вы убедитесь, что последующие конвейеры не будут вызваны. Но если вы возвращаете элемент, то возвращаемый элемент передается следующему конвейеру. В вашем случае, поскольку вы ничего не возвращали в первом конвейере, следующий конвейер получил None в параметре item и, следовательно, ошибку. Поэтому убедитесь, что вы возвращаете товар в каждом конвейере

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...