Как запустить несколько версий одного паука одновременно с помощью Scrapy?

Моя проблема заключается в следующем:

Чтобы выиграть время, я хотел бы запустить несколько версий одного паука. Процесс (разбор определений) одинаков, элементы одинаковы, а коллекция в базе данных одинакова. Что меняется, так это переменная start_url. Это выглядит так:

"https://www.website.com/details/{0}-{1}-{2}/{3}/meeting".format(year,month,day,type_of_meeting)

Учитывая, что дата совпадает, например, 2018-10-24, я хотел бы запустить две версии одновременно:

  • версия 1 type_of_meeting = pmu
  • версия 2 с type_of_meeting = pmh

Это первая часть моей проблемы. И вот мне интересно, если я должен создать два разных класса в одном пауке, как class SpiderPmu(scrapy.Spider): а также class SpiderPmh(scrapy.Spider): в spider.py, Но если это лучший способ, который, по вашему мнению, я должен сделать, я не знаю, как это реализовать, учитывая settings.py, pipelines.py. Я уже читал о CrawlerProcess от scrapy.crawler модуль, но я не очень хорошо понимаю, как реализовать его в моем проекте. составлять тему, scrapy doc. Я не уверен, что часть process = CrawlerProcess() process.crawl(MySpider1) process.crawl(MySpider2) process.start() должен быть в файле spider.py. Прежде всего, я не уверен, что это отвечает на мои проблемы.

Вторая часть - как запустить несколько версий с учетом разных интервалов дат.

Я уже создал некоторый диапазон интервалов в своем классе пауков как:

  • year = range(2005,2019)
  • month = range(1,13)
  • day = range(1,32)

и поместите это в петлю. Это хорошо работает.

Но чтобы выиграть время, я хотел бы запустить несколько пауков, с разными интервалами лет.

  • 1-я версия с year = range(2005,2007)
  • 2-я версия с year = range(2007,2009)
  • и так до тех пор, пока year = range(2017,2019)

Семь версий одновременно означают в семь раз быстрее.

Я мог бы создать 7 разных проектов для каждого диапазона лет, но я думаю, что это не самый умный способ... и я не уверен, создаст ли он конфликт для использования одной и той же базы данных для 7 запущенных проектов. в то же время.

Я ожидаю сделать что-то вроде открытия 7 команд:

  1. scrapy crawl spiderpmu для версии type_of_race = pmu
  2. "Enter a range of year": с raw_input = 2010, 2012 ==> range(2010,2012)
  3. Паук ползет

параллельно, если это обязательно, сделать:

  1. scrapy crawl spiderpmh для версии type_of_race = pmh
  2. "Enter a range of year": с raw_input = 2010, 2012 ==> range(2010,2012)
  3. Паук ползет

Возможно использование одного единственного паука или одного единственного проекта при необходимости.

Как я могу сделать?

PS: Я уже договорился с ProLipo в качестве прокси, сетью Tor, чтобы сменить IP, и USER_AGENT всегда меняется. Таким образом, я избегаю быть забаненным, проползая одновременно с несколькими пауками. И мой паук "вежливый" с AUTOTHROTTLE_ENABLED = True, Я хочу держать это вежливо, но быстрее.

Версия Scrapy: 1.5.0, версия Python: 2.7.9, версия Mongodb: 3.6.4, версия Pymongo: 3.6.1

2 ответа

Scrapy поддерживает аргументы паука. Достаточно странно, что нет простой документации, но я постараюсь заполнить:

Когда вы запускаете crawl команда, которую вы можете предоставить -a NAME=VALUE аргументы, и они будут установлены в качестве переменных экземпляра вашего класса паука. Например:

class MySpider(Spider):
    name = 'arg'
    # we will set below when running the crawler
    foo = None 
    bar = None

    def start_requests(self):
        url = f'http://example.com/{self.foo}/{self.bar}'
        yield Request(url)

И если мы запустим это:

scrapy crawl arg -a foo=1 -a bar=2
# will crawl example.com/1/2

Итак, я нахожу решение, вдохновленное scrapy crawl -a variable = value

Относящийся к пауку, в папке "spiders" был преобразован:

class MySpider(scrapy.Spider):
name = "arg"
allowed_domains = ['www.website.com']

    def __init__ (self, lo_lim=None, up_lim=None , type_of_race = None) : #lo_lim = 2017 , up_lim = 2019, type_of_race = pmu
        year  = range(int(lo_lim), int(up_lim)) # lower limit, upper limit, must be convert to integer type, instead this is string type
        month = range(1,13) #12 months
        day   = range(1,32) #31 days
        url   = []
        for y in year:
            for m in month:
                for d in day:
                    url.append("https://www.website.com/details/{}-{}-{}/{}/meeting".format(y,m,d,type_of_race))

        self.start_urls = url #where url = ["https://www.website.com/details/2017-1-1/pmu/meeting",
                                        #"https://www.website.com/details/2017-1-2/pmu/meeting",
                                        #...
                                        #"https://www.website.com/details/2017-12-31/pmu/meeting"
                                        #"https://www.website.com/details/2018-1-1/pmu/meeting",
                                        #"https://www.website.com/details/2018-1-2/pmu/meeting",
                                        #...
                                        #"https://www.website.com/details/2018-12-31/pmu/meeting"]

    def parse(self, response):
        ...`

Затем он отвечает на мою проблему: держать одного паука и запускать несколько его версий несколькими командами одновременно без проблем.

Без def __init__ это не сработало для меня. Я перепробовал много способов, вот этот совершенный код, который работает для меня.

Версия Scrapy: 1.5.0, версия Python: 2.7.9, версия Mongodb: 3.6.4, версия Pymongo: 3.6.1

Другие вопросы по тегам