如何在Scrapy Spider中传递用户定义的参数


100

我正在尝试将用户定义的参数传递给Scrapy的Spider。有人可以建议如何做吗?

我在-a某处读到一个参数,但不知道如何使用它。

Answers:


188

蜘蛛形参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年更新:使用较新的基类并添加超级类,谢谢@Birla

2017年更新:使用Python3 super

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

更新2018@eLRuLL指出,蜘蛛可以将参数作为属性访问


3
爬网爬虫myspider -a类别=电子产品-a域=系统
Steven Almeroth

1
上面的代码仅对我有用。例如。如果我使用定义域self.domain,那么我仍然无法在__init__方法之外访问它。Python引发未定义的错误。顺便说一句,您为什么省略了super通话?PS。我正在使用CrawlSpider类
Birla

2
@FlyingAtom如果我误解了,请纠正我,但是这些并发调用中的每个调用都会是蜘蛛的不同实例,不是吗?
L Lawliet

1
@Birla,在构造函数中使用self.domain = domain来填充类范围变量。
哈桑·拉扎

1
@nealmcb __init__是蜘蛛类的方法。它的实现本身并不会降低蜘蛛的鲁棒性,它包含在答案中以表明您可以声明关键字参数的默认值,但正如您所说的那样,它是可选的。正如我们去年指出的那样,您不需要使用getattr就可以将参数作为属性来访问,例如self.category,正如我们在答案中所看到的那样self.domain
Steven Almeroth

31

先前的答案是正确的,但是您不必__init__每次想要编写scrapy的Spider时都声明构造函数(),只需像以前一样指定参数即可:

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

而且就可以了。


4
真正。输入python的阴暗面。
巴尼(Barney)

14

通过爬网命令传递参数

抓取抓取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选项在运行检索命令时会传递蜘蛛参数。例如,如果我想将域名作为参数传递给我的Spider,那么我将这样做-

scrapy抓取myspider -a domain =“ http://www.example.com”

并在Spider的构造函数中接收参数:

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和Spider名称。ScrapyD具有api来停止/启动/状态/列出蜘蛛。

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

scrapyd-deploy将以鸡蛋的形式将蜘蛛部署到守护程序中,甚至可以维护蜘蛛的版本。启动Spider时,您可以提及要使用哪个版本的Spider。

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"

附加的优点是您可以构建自己的UI来接受用户的url和其他参数,并使用上面的scrapy schedule API安排任务

有关更多详细信息,请参阅scrapyd API文档

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.