Оформление скрапа. Запрос детеминистики? - PullRequest
0 голосов
/ 08 мая 2018

Это не проблема для меня, я могу жить без этого, но мне просто любопытно, возможно ли это и как.

Сегодня я узнал, что scrapy.Request не завершится в том же порядке, в котором они были запущены.

Пример псевдокода:

class SomeSpider(scrapy.Spider):
    def parse(self, response):

        # get all ads(25) from ads list
        for ad in adList():
            add_url = findAddUrl()
            yield scrapy.Request(add_url, callback=self.parseAd)

        # go to next page
        if some_condition_OK:
             next_page_url = findNextpageUrl()
             yield scrapy.Request(next_page_url)
        else:
            print 'Stoped at.'

    def parseAd(self, response):
        field_1 = get_field_1()
        field_n = get_field_n()

        # save field_1 to field_n to sqlite DB

Это упрощенный пример паука, который я кодировал, и он работает нормально.

Но сегодня я узнал, что yield scrapy.Request не закончится в том же порядке, в каком они были начаты.

В моем примере на каждой странице по 25 объявлений для каждой страницы, я начинаю yield scrapy.Request(add_url, callback=self.parseAd), чтобы получать больше информации от каждого объявления.
И после этого я перехожу на следующую страницу с yield scrapy.Request(next_page_url).
Но я заметил, что некоторые объявления со страницы 2 будут заканчиваться раньше всех объявлений со страницы 1.
Я понимаю почему и вижу выгоду от такого подхода.

Но мой вопрос: можно ли сделать scrapy.Request детерминированным?

Под детерминизмом я подразумеваю, что каждый scrapy.Request будет заканчиваться в том же порядке, в котором он был запущен.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Единственный способ сделать Scrapy детерминированным - выдавать только один запрос одновременно, оставляя остальные из них в списке или очереди:

class SomeSpider(scrapy.Spider):

    pending_request = []

    def parse(self, response):

        # get all ads(25) from ads list
        for ad in adList():
            add_url = findAddUrl()
            self.pending_request.append(
                scrapy.Request(add_url, callback=self.parseAd))

        # go to next page
        if some_condition_OK:
             next_page_url = findNextpageUrl()
             self.pending_request.append(scrapy.Request(next_page_url))
        else:
            print 'Stoped at.'

        if self.pending_request:
            yield self.pending_request.pop(0)

    def parseAd(self, response):
        field_1 = get_field_1()
        field_n = get_field_n()

        if self.pending_request:
            yield self.pending_request.pop(0)
0 голосов
/ 08 мая 2018

Добавить эти настройки:

DOWNLOAD_DELAY

Default: 0

DOWNLOAD_DELAY = 0,25 # 250 мс задержки

Но scrapy также имеет функцию автоматической настройки задержек загрузки, которая называется AutoThrottle. Он автоматически устанавливает задержки в зависимости от нагрузки как сервера Scrapy, так и веб-сайта, который вы сканируете. Это работает лучше, чем установка произвольной задержки.

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