如何将实例变量添加到Scrapy CrawlSpider?

时间:2016-08-27 22:08:25

标签: python scrapy scrapy-spider

我正在运行一个CrawlSpider,我希望通过将函数传递给process_request来实现一些逻辑,以便在中途停止关注某些链接。

此功能使用蜘蛛的变量来跟踪当前状态,并根据它(以及引用网址),链接被删除或继续处理:

class BroadCrawlSpider(CrawlSpider):
    name = 'bitsy'
    start_urls = ['http://scrapy.org']
    foo = 5

    rules = (
        Rule(LinkExtractor(), callback='parse_item', process_request='filter_requests', follow=True),
    )

    def parse_item(self, response):
        <some code>

    def filter_requests(self, request):
        if self.foo == 6 and request.headers.get('Referer', None) == someval:
             raise IgnoreRequest("Ignored request: bla %s" % request)
        return request

我认为如果我在同一台机器上运行多个蜘蛛,它们都会使用相同的变量,这不是我的意图。

有没有办法将实例变量添加到CrawlSpiders?我运行Scrapy时是否只创建了一个蜘蛛实例?

我可能会使用一个包含每个进程ID值的字典解决它,但这将是丑陋的......

1 个答案:

答案 0 :(得分:1)

我认为spider arguments将是您案例中的解决方案。

当调用像scrapy crawl some_spider这样的scrapy时,你可以添加像scrapy crawl some_spider -a foo=bar这样的参数,蜘蛛会通过它的构造函数接收值,例如:

class SomeSpider(scrapy.Spider):
    def __init__(self, foo=None, *args, **kwargs):
        super(SomeSpider, self).__init__(*args, **kwargs)
        # Do something with foo

更重要的是,作为scrapy.Spider actually sets all additional arguments as instance attributes,您甚至不需要显式覆盖__init__方法,只需访问.foo属性即可。 :)