Scrapy: как вручную вставить запрос из обратного вызова события spider_idle?

Я создал паука и связал метод с событием spider_idle.

Как добавить запрос вручную? Я не могу просто вернуть элемент из синтаксического анализа — синтаксический анализ в этом случае не выполняется, так как все известные URL-адреса были проанализированы. У меня есть метод для создания новых запросов, и я хотел бы запустить его из обратного вызова Spider_idle, чтобы добавить созданные запросы.

class FooSpider(BaseSpider):
    name = 'foo'

    def __init__(self):
        dispatcher.connect(self.dont_close_me, signals.spider_idle)

    def dont_close_me(self, spider):
        if spider != self:
            return
        # The engine instance will allow me to schedule requests, but
        # how do I get the engine object?
        engine = unknown_get_engine()
        engine.schedule(self.create_request())

        # afterward, ensure we stay alive by raising DontCloseSpider
        raise DontCloseSpider("..I prefer live spiders.")

ОБНОВЛЕНИЕ: я решил, что мне, вероятно, нужен объект ExecutionEngine, но я точно не знаю, как получить его от паука, хотя он доступен из экземпляра Crawler.

ОБНОВЛЕНИЕ 2: .. спасибо. ..crawler присоединен как свойство суперкласса, поэтому я могу просто использовать self.crawler без дополнительных усилий. >.>


person Mr. B    schedule 06.06.2013    source источник


Ответы (1)


class FooSpider(BaseSpider):
    def __init__(self, *args, **kwargs):
        super(FooSpider, self).__init__(*args, **kwargs)
        dispatcher.connect(self.dont_close_me, signals.spider_idle)

    def dont_close_me(self, spider):
        if spider != self:
            return

        self.crawler.engine.crawl(self.create_request(), spider)

        raise DontCloseSpider("..I prefer live spiders.")

Обновление 2016:

class FooSpider(BaseSpider):
    yet = False

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        from_crawler = super(FooSpider, cls).from_crawler
        spider = from_crawler(crawler, *args, **kwargs)
        crawler.signals.connect(spider.idle, signal=scrapy.signals.spider_idle)
        return spider

    def idle(self):
        if not self.yet:
            self.crawler.engine.crawl(self.create_request(), self)
            self.yet = True
person Steven Almeroth    schedule 06.06.2013
comment
Фу. Непосредственно часть моего суперкласса. ›.› - person Mr. B; 07.06.2013
comment
.. Я написал крошечное расширение, чтобы прикрепить сканер к классу, но это, очевидно, правильный путь. - person Mr. B; 07.06.2013
comment
Не могли бы вы объяснить, что делает вышеуказанная функция. Я еще не понял, что делает. Можете ли вы также объяснить отличие от def spider_idle(self): self.crawler.engine.slot.scheduler.next_request() поднять DontCloseSpider - person Ronak Agrawal; 21.11.2017