scrapy: запрос доходности от обратного вызова, вызванного сигналом - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть паук, который очищает некоторые данные и возвращает элемент в конвейер. Затем конвейер проверяет, существуют ли эти данные в базе данных. Если это не так, он бросает предмет. Паук является сигналом, подключенным для вызова обратного вызова по сигналу item_drop. Я бы хотел выдать другой запрос на другой URL из обратного вызова item_dropped, чтобы заполнить этот же элемент дополнительными данными. Если я не включаю выражение yield в обратный вызов, оно срабатывает, но если я это делаю, то не делает, и я не уверен, почему.

(упрощенно для краткости)

MySpider.py:

def from_crawler(cls, crawler, *args, **kwargs):
        spider = super(MySpider, cls).from_crawler(crawler, *args, **kwargs)
        crawler.signals.connect(spider.item_dropped, signal=signals.item_dropped)
        return spider

[ ...parse start url and yield to pipeline here... ]

def item_dropped(self, item, response, exception, spider,):
        print("ITEM ERROR CAUGHT")
        yield Request(
            url="http://www.example.com/api/data",
            callback=self.parse_request_2,
            cb_kwargs=dict(item=item))

MyPipeline.py:

def process_item(self, item, spider):

    /* ORM model mapping */
    data = Data(
      name = item['name']
    )

    data_exists = self.session.query(exists().where(Data.name == item['name'])).scalar()


    if data_exists is False:
      raise DropItem("DATA_INCOMPLETE")

Причина, по которой я пытаюсь сделать это, заключается в том, что новые объекты постоянно добавляются в первый URL, поэтому мне нужно периодически очищать его, но он не содержит все данные, необходимые для этого элемента. Затем мне нужно очистить другой URL-адрес для добавления дополнительных данных к этому элементу, но только один раз, при первом добавлении этого элемента в базу данных.

Как получить скрап для получения другого запроса изнутри обратный вызов item_dropped? Что еще более важно, я иду по этому пути правильно, или есть лучший способ сделать это? Я знаю, что мог бы выполнить проверку БД изнутри паука и просто реализовать там логи обратного вызова c, но я бы предпочел, чтобы и паук, и конвейер не открывали сеансы БД.

1 Ответ

1 голос
/ 23 апреля 2020

Вы не можете выдавать запросы от этого сигнала.

Вы должны либо переместить свой код в промежуточное программное обеспечение паука , либо переместить его в обратный вызов запроса в вашем пауке.

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