上一章提到scrapy的启动是通过ScrapyCommand对象中的crawler_process实现的,crawler_process是通过crawler.py下的CrawlerProcess类创建的实例。该文件下定义了Crawler,CrawlerProcess和CrawlerRunner三个类。
CrawlerProcess是CrawlerRunner的子类,而命令文件中的self.crawler_process实例的crawl方法就是对CrawlerRunner的crawl方法的继承。
(1)crawl(spname, **opts.spargs)
根据传入的spider名创建Crawler对象,然后调用_crawl方法进行整个抓取流程的运行。
Crawler对象的属性里就有Scrapy流程图中都很熟悉的spider,engine。在crawl方法中对spider和engine进行了初始化,并开启了engine的调度。
代码里可以看到defer.inlineCallbacks这个装饰器,Scrapy是基于twisted进行异步操作的,
这个装饰器的作用会让函数运行后返回一个deferred对象,deferred可以看做是管理回调函数的链表。
Crawler的crawl方法
CrawlerRunner的crawl方法
(2)start()
stop_after_crawl参数表示是否在在所有crawlers完成之后停止reactor,之前提到过deferred相当于一个事件的链表,而reactor则可以看做是这个链表的消费者。
join方法中通过对_active这个集合的判断为空时,才会跳出循环,CrawlerRunner的_crawl方法中_active这个属性保存了调用crawl方法返回的deferred对象,当结束后会从这个集合中删除对应的deferred对象。
然后是通过配置对reactor进行初始化,并开启reactor的运行。