Python 如何在scrapy spider中传递用户定义的参数

Python 如何在scrapy spider中传递用户定义的参数,python,scrapy,web-crawler,Python,Scrapy,Web Crawler,我试图将用户定义的参数传递给scrapy's spider。有人能建议怎么做吗 我在某个地方读到一个参数-a,但不知道如何使用它。爬行器参数是使用-a选项在爬网命令中传递的。例如: scrapy crawl myspider -a category=electronics -a domain=system 爬行器可以作为属性访问参数: class MySpider(scrapy.Spider): name = 'myspider' def __init__(self, cat

我试图将用户定义的参数传递给scrapy's spider。有人能建议怎么做吗


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

爬行器参数是使用
-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文档:

更新2013:添加第二个参数

2015年更新:调整措辞

更新2016:使用更新的基类并添加super,谢谢@Birla

2017年更新:使用Python3 super

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

更新2018:,爬行器可以作为属性访问参数

以使用爬网命令传递参数


scrapy crawl myspider-a category='mycategory'-a domain='example.com'

若要传递要在上运行的参数,请将-a替换为-d

旋度-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将所有参数作为spider属性,您可以完全跳过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','')


爬行器参数是在使用-a选项运行爬网命令时传递的。例如,如果我想将域名作为参数传递给我的爬行器,那么我将这样做-

搔痒抓取糠秕-一个域=”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]
        #


它将起作用:)

前面的答案是正确的,但您不必声明构造函数(
\uuuu init\uuuu
),每次您要为scrapy的爬行器编码时,您只需像以前一样指定参数即可:

scrapy crawl myspider -a parameter1=value1 -a parameter2=value2
在spider代码中,您可以将它们用作spider参数:

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
或者我们可以使用它来公开一个API,在这里我们可以传递开始url和蜘蛛名称。ScrapyD具有停止/启动/状态/列出爬行器的api

pip install scrapyd scrapyd-deploy
scrapyd
scrapyd-deploy local -p default
scrapyd deploy
将以egg的形式将spider部署到守护进程中,甚至它会维护spider的版本。在启动spider时,您可以提到要使用哪个版本的spider

class MySpider(CrawlSpider):

    def __init__(self, start_urls, *args, **kwargs):
        self.start_urls = start_urls.split('|')
        super().__init__(*args, **kwargs)
    name = testspider
curlhttp://localhost:6800/schedule.json -d project=default-d spider=testspider-d start\u url=”https://www.anyurl...|https://www.anyurl2“

另外一个优点是,您可以构建自己的UI,以接受来自用户的url和其他参数,并使用上面的scrapyd schedule API计划任务


如需更多详细信息,请参阅“抓痒”myspider-a category=electronics-a domain=system上述代码仅部分适用于我。例如,如果我使用
self.domain
定义域,我仍然无法在
\uuuu init\uuuu
方法之外访问它。Python抛出一个未定义的错误。顺便问一下,你为什么省略了
super
呼叫?另外,我在和爬行蜘蛛一起工作class@FlyingAtom若我误解了,请纠正我,但这些并发调用中的每一个都是spider的不同实例,不是吗?@Birla,在构造函数中使用self.domain=domain来填充类范围变量。@nealmcb
\uuu init\uuu
是spider类的一个方法。它的实现本身并没有降低spider的健壮性,答案中包含了它,以表明您可以为关键字参数声明默认值,但正如您所说的,它是可选的。正如我们去年指出的,您不需要使用
getattr
,您只需将参数作为属性访问,例如
self.category
,或者正如我们在回答
self.domain
True中看到的那样。进入python的黑暗面。简洁、健壮、灵活!