Как передать определенный пользователем аргумент в scrapy spider

100

Я пытаюсь передать определенный пользователем аргумент пауку scrapy. Может ли кто-нибудь подсказать, как это сделать?

Я -aгде-то читал о параметре, но понятия не имею, как его использовать.

Л. Лоулит
источник

Ответы:

190

Аргументы паука передаются в crawlкоманде с помощью -aпараметра. Например:

scrapy crawl myspider -a category=electronics -a domain=system

Пауки могут обращаться к аргументам как к атрибутам:

class MySpider(scrapy.Spider):
    name = 'myspider'

    def __init__(self, category='', **kwargs):
        self.start_urls = [f'http://www.example.com/{category}']  # py36
        super().__init__(**kwargs)  # python3

    def parse(self, response)
        self.log(self.domain)  # system

Взято из документа Scrapy: http://doc.scrapy.org/en/latest/topics/spiders.html#spider-arguments

Обновление 2013 : добавить второй аргумент

Обновление 2015 : изменить формулировку

Обновление 2016 : используйте более новый базовый класс и добавьте super, спасибо @Birla

Обновление 2017 : используйте Python3 super

# previously
super(MySpider, self).__init__(**kwargs)  # python2

Обновление 2018 : как указывает @eLRuLL , пауки могут получать доступ к аргументам как к атрибутам

Стивен Альмерот
источник
3
scrapy crawl myspider -a category = electronics -a domain = system
Steven Almeroth
1
Приведенный выше код работает только частично. Например, Если я определю использование домена self.domain, я все равно не смогу получить к нему доступ вне __init__метода. Python выдает неопределенную ошибку. Кстати, почему вы пропустили superзвонок? PS. Я работаю с классом CrawlSpider
Бирла,
2
@FlyingAtom Пожалуйста, поправьте меня, если я неправильно понял, но каждый из этих одновременных вызовов будет разными экземплярами паука, не так ли?
L Lawliet,
1
@Birla, используйте self.domain = domain в конструкторе для заполнения переменной области видимости класса.
Хасан Раза
1
@nealmcb __init__- это метод класса паука. Его реализация сама по себе не делает паука менее надежным, и он включен в ответ, чтобы показать, что вы можете объявить значения по умолчанию для аргументов ключевого слова, но, как вы сказали, это необязательно. Как мы указывали в прошлом году, вам не нужно использовать, getattrвы можете просто получить доступ к аргументам как к атрибутам, например, self.categoryили как мы видим в ответеself.domain
Стивен Альмерот
33

Предыдущие ответы были правильными, но вам не нужно объявлять конструктор ( __init__) каждый раз, когда вы хотите закодировать паук scrapy, вы можете просто указать параметры, как и раньше:

scrapy crawl myspider -a parameter1=value1 -a parameter2=value2

и в вашем коде паука вы можете просто использовать их как аргументы паука:

class MySpider(Spider):
    name = 'myspider'
    ...
    def parse(self, response):
        ...
        if self.parameter1 == value1:
            # this is True

        # or also
        if getattr(self, parameter2) == value2:
            # this is also True

И это просто работает.

eLRuLL
источник
4
Правда. Войдите на темную сторону питона.
Barney
14

Передача аргументов с помощью команды сканирования

сканирование scrapy myspider -a category = 'mycategory' -a domain = 'example.com'

Чтобы передать аргументы для запуска на scrapyd, замените -a на -d

curl http://your.ip.address.here:port/schedule.json -d spider = myspider -d category = 'mycategory' -d domain = 'example.com'

Паук получит аргументы в своем конструкторе.


class MySpider(Spider):
    name="myspider"
    def __init__(self,category='',domain='', *args,**kwargs):
        super(MySpider, self).__init__(*args, **kwargs)
        self.category = category
        self.domain = domain

Scrapy помещает все аргументы как атрибуты паука, и вы можете полностью пропустить метод init . Остерегайтесь использовать метод getattr для получения этих атрибутов, чтобы ваш код не сломался.


class MySpider(Spider):
    name="myspider"
    start_urls = ('https://httpbin.org/ip',)

    def parse(self,response):
        print getattr(self,'category','')
        print getattr(self,'domain','')
Хасан Раза
источник
Кратко, надежно и гибко!
nealmcb
8

Аргументы паука передаются при выполнении команды обхода с помощью параметра -a. Например, если я хочу передать имя домена в качестве аргумента своему пауку, я сделаю следующее:

сканирование scrapy myspider -a domain = "http://www.example.com"

И получить аргументы в конструкторах паука:

class MySpider(BaseSpider):
    name = 'myspider'
    def __init__(self, domain='', *args, **kwargs):
        super(MySpider, self).__init__(*args, **kwargs)
        self.start_urls = [domain]
        #

...

это сработает :)

Сиярам Малав
источник
0

В качестве альтернативы мы можем использовать ScrapyD, который предоставляет API, в котором мы можем передать start_url и имя паука. ScrapyD имеет API для остановки / запуска / статуса / вывода списка пауков.

pip install scrapyd scrapyd-deploy
scrapyd
scrapyd-deploy local -p default

scrapyd-deployразвернет паука в форме яйца в демона, и даже он поддерживает версию паука. При запуске паука вы можете указать, какую версию паука использовать.

class MySpider(CrawlSpider):

    def __init__(self, start_urls, *args, **kwargs):
        self.start_urls = start_urls.split('|')
        super().__init__(*args, **kwargs)
    name = testspider

curl http://localhost:6800/schedule.json -d project=default -d spider=testspider -d start_urls="https://www.anyurl...|https://www.anyurl2"

Дополнительным преимуществом является то, что вы можете создать свой собственный пользовательский интерфейс, чтобы принимать URL-адрес и другие параметры от пользователя и планировать задачу с помощью вышеуказанного API расписания scrapyd.

Обратитесь к документации scrapyd API для более подробной информации.

Нагендран
источник