Как запустить несколько версий одного паука одновременно с помощью 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 команд:
scrapy crawl spiderpmu
для версииtype_of_race = pmu
"Enter a range of year":
сraw_input = 2010, 2012
==>range(2010,2012)
- Паук ползет
параллельно, если это обязательно, сделать:
scrapy crawl spiderpmh
для версииtype_of_race = pmh
"Enter a range of year":
сraw_input = 2010, 2012
==>range(2010,2012)
- Паук ползет
Возможно использование одного единственного паука или одного единственного проекта при необходимости.
Как я могу сделать?
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