(四)Scrapy的抓取流程——Engine

上一篇提到在Crawler的crawl方法中,启动了Engine。而如Scrapy流程图中描述的,抓取的流程由Engine主导完成。engine是ExecutionEngine的实例,初始化时会初始化诸如scheduler、downloader、scraper(itempipeline和spidermiddleware这一块)等属性。
Scrapy流程图

目录结构
engine.py所在的目录,抓取流程中的主要模块。
在这里插入图片描述
ExecutionEngine的__init__方法,初始化抓取流程中用到的各个控件。

还是从上一章里的open_spider和start两个方法来看流程。

(1)open_spider
首先会根据spider对象里的start_urls获取到初始链接,然后由scheduler来对初始链接进行调度,在这一步之前,仍会经过spider中间件的process_start_requests方法(记得有些教程说的是直接从spider这儿取链接到scheduler,没有提到spider中间件)。
这个slot对象可以看做是请求的状态,来管理engine的运行状态和正在请求的request的管理。而所谓的scheduler对request的操作,则都是通过slot来完成的。

@defer.inlineCallbacks
def open_spider(self, spider, start_requests=(), close_if_idle=True):
    assert self.has_capacity(), "No free spider slot when opening %r" % \
        spider.name
    logger.info("Spider opened", extra={'spider': spider})
    nextcall = CallLaterOnce(self._next_request, spider)
    scheduler = self.scheduler_cls.from_crawler(self.crawler)
    start_requests = yield self.scraper.spidermw.process_start_requests(start_requests, spider)
    slot = Slot(start_requests, close_if_idle, nextcall, scheduler) # 使用scheduler初始化slot
    self.slot = slot
    self.spider = spider
    yield scheduler.open(spider) # 对scheduler的初始化(spider,队列, 过滤器)
    yield self.scraper.open_spider(spider) # 初始化scraper中的spider,后续分配任务用
    self.crawler.stats.open_spider(spider) # 状态收集器,字典方式保存数据。默认是MemoryStatsCollector
    yield self.signals.send_catch_log_deferred(signals.spider_opened, spider=spider)
    slot.nextcall.schedule() # 请求入队操作
    slot.heartbeat.start(5)  # 下次请求的时间,又因为默认是即时触发方法,所以并不会等待5秒。

在这里插入图片描述

self.heartbeat = task.LoopingCall(nextcall.schedule)
slot.heartbeat.start(5)
在这里设置的下次运行的时间间隔为5秒,可我们在使用scrapy时并没有感受到5秒的间隔,因为在start方法中now默认设置为True,会即时执行。
在这里插入图片描述

(2)start
这儿并没有比较重要的启动代码;记录了时间,将状态进行了设置。并创建了一个deferred的对象,会在关闭engine时调用。

@defer.inlineCallbacks
def start(self):
    """Start the execution engine"""
    assert not self.running, "Engine already running"
    self.start_time = time()
    yield self.signals.send_catch_log_deferred(signal=signals.engine_started)
    self.running = True
    self._closewait = defer.Deferred()
    yield self._closewait
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值