解读scrapy各个组件中的from_crawler()方法

Scrapy 中很多组件都有 from_crawler()方法,下面是我读源码后对 from_crawler()方法的理解,记录下来。

from_crawler() 方法一般用传入的参数来实例化一个对象,比如 scrapy.spider 中的 from_crawler():

@classmethod
def from_crawler(cls, crawler, *args, **kwargs):    
        spider = cls(*args, **kwargs)   # 第一步:携带参数实例化这个类
        spider._set_crawler(crawler)    # 第二步:将 crawler 传递给实例,使新实例有crawler属性和settings参数
        return spider       # 返回类的实例对象

然后再 scrapy.crawler.Crawler._create_spider() 中调用:

def _create_spider(self, *args, **kwargs):  
    return self.spidercls.from_crawler(self, *args, **kwargs)

spider 中的 from_crawler() 比较就是最浅显易懂的例子,但也包含最核心的两步:

(1) 用携带的参数来实例化类,一般用 cls();

(2)将crawler 传递给新创建的实例,使新实例有 crawler 的属性和 settings 配置的参数。

 

各个组件是如何调用 from_crawler()方法的呢?下面以 scheduler 为例子:

scrapy.core.engine.ExecutionEngine.open_spider() 中,调用了 scheduler 的 from_crawler()方法来生成 scheduler

scheduler = self.scheduler_cls.from_crawler(self.crawler)

因为,这是 ExecutionEngine 的方法调用的,所以参数 "self.crawler" 中的 self 是 ExecutionEngine,而 ExecutionEngine 是 scrapy.crawler.Crawler._create_engine() 方法创建的:

# Crawler 中 ExecutionEngine 对象的创建
def _create_engine(self):
    return ExecutionEngine(self, lambda _: self.stop())  # crawler将self对象传入创建ExecutionEngine

所以传入 from_crawler(self.crawler) 的 self.crawler 就是 scrapy.crawler.Crawler 对象。

 

总结一下:

from_crawler() 用于根据传入的参数和 crawler 对象来生成 scheduler,使得scheduler有crawler的属性和配置。

`from_crawler`是Scrapy的一个类方法,用于创建一个新的Spider实例。它是Scrapy的一个特殊方法,因为它可以访问Scrapy的核心组件和配置,例如Crawler对象、Settings对象和Signal manager。 `from_crawler`有一个默认的实现,它将Crawler对象、Settings对象和其他参数传递给Spider的构造函数。您可以重写这个方法来自定义Spider的初始化过程,例如添加信号处理程序或在Spider创建时执行其他任务。 以下是一个常见的使用`from_crawler`方法的示例,它在Spider创建时添加了一个信号处理程序,以便在Spider完成时关闭数据库连接: ```python from scrapy import signals class MySpider(scrapy.Spider): name = 'myspider' def __init__(self, *args, **kwargs): super(MySpider, self).__init__(*args, **kwargs) self.connection = None @classmethod def from_crawler(cls, crawler, *args, **kwargs): spider = super(MySpider, cls).from_crawler(crawler, *args, **kwargs) crawler.signals.connect(spider.spider_closed, signal=signals.spider_closed) return spider def spider_closed(self, spider): if self.connection is not None: self.connection.close() def parse(self, response): # 爬虫代码 ``` 在这个例子,我们定义了一个名为`spider_closed`的方法,它在Spider完成时被调用。我们通过重写`from_crawler`方法来绑定这个方法,以便在创建Spider实例时添加信号处理程序。`spider_closed`方法检查数据库连接是否存在,并在存在时关闭连接。 请注意,`from_crawler`是一个类方法,它需要返回一个新的Spider实例。因此,在实现`from_crawler`方法时,您需要使用`super()`方法调用父类的`from_crawler`方法,然后返回新的Spider实例。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值