爬虫 Scrapy 学习系列之二:Architect 架构篇

前言

这是 Scrapy 系列学习文章之一,笔者打算撰写该系列文章用来记录自己再学习并使用 Scrapy 的点滴;

本文重点从 Scrapy 的顶层架构进行阐述;

本文为作者的原创作品,转载需注明出处;

架构

数据流设计图

Scrapy 的整个架构如图所示,

总共有八个步骤,该八个步骤的流转都依赖于 ENGINE 模块;下面我们就依次的来梳理一下整个调用流程,

  1. Engine 先从 Spider 中得到初始的 Requests,Requests 将会被用来进行爬去;
  2. Engine 将得到的 Requests 放入 Scheduler 中,然后不断从 Scheduler 询问下次可以进行爬去的 Requests;
  3. Scheduler 返回下一次需要被爬取的 Requests 给 Engine;
  4. Engine 再将 Requests 发送给 Downloader,通过 Downloader Middlewares 的 process_request() 方法进行传递;
  5. 一旦 Downloader 完成了对该页面的下载,Downloader 将会生成一个与该页面相关的 Response 对象,然后将其反馈给 Engine;通过 Downloader Middlewares 的 process_response() 方法进行传递;
  6. Engine 从 Downloader 得到 Response 以后再发送给 Spider 进行处理;通过 Spidder Middlewares 的 process_spider_input() 方法进行传递;
  7. Spider 处理从 Engine 返回的 Reponse 对象,返回被爬取的 items 和新的 Requests 给 Engine 继续处理;通过 Spider Middlewares 的 process_spider_output() 方法进行传递;
  8. Engine 发送已经被处理的 Items 到 Item Pipelines,然后将新的 Requests 发送给 Scheduler 请求下一次可能的新的 Request 进行爬取;
  9. 从第一步开始重复整个流程,直到 Scheduler 中没有新的 Requests;

模块

Scrapy Engine

Scrapy Engine 的职责主要就是作为核心引擎来控制所有组件之间的数据流转,然后当特殊的动作发生以后触发相关的事件(Event);

Scheduler

Scheduler 从 Engine 当中获取 Requests,然后将它们放入队列当中,当 Engine 需要它们的时候,触发它们;

Downloader

Downloader 的职责主要是取得 web 页面,然后将它们返回给 Engine,Engine 再将它们反馈给 Spider;

Spiders

Spiders 是一些由用户自定义的类,用来解析 Responses 并提取相关的元素 items;

Item Pipeline

Item Pipeline 的主要职责是处理 Spider 提取完成的 items;典型的任务有,对已提取的数据进行清洗,验证和持久化处理;

Downloader middleware

Downlaoder 中间件是一个位于 Engine 和 Downloader 之间的一个特殊的“钩子(hook)”,主要处理从 Engine 发送给 Downloader 的 Requests,以及从 Downloader 传递给 Engine 的 Responses;

当你有如下几种情况的时候,需要使用到 Downloader 中间件,

  • 在 Request 需要发送给 Downloader 之前需要做一些特殊的处理;应用场景其实也就是,在 Scrapy 发送请求给被爬取页面之前做一些相关的处理);
  • 在将 response 发送给 spider 之前做一些特殊的处理;
  • 取而代之,发送一个新的 Request 给 Spider,而不再是发送一个 Reponse 给 Spider
  • 在不获取网页内容的前提下传递一个 Response 给 Spider
  • 过滤掉一些 Requests;

Spider middleware

Spider 中间件是 Engine 和 Spiders 之间的一个特殊的钩子(hook),可以处理 spider 的 input(reponses) 和 output(items 和 requests);

当你需要执行如下操作的时候,需要使用一个 Spider 中间件

  • 在 Spider output 动作以后执行后续的操作,修改、添加、删除 requests 或者 items;
  • post-process start_requests;
  • 处理 spider 的异常;
  • 调用一个 errback 方法而不是通过 response 的内容回调一些新的 requests;

Event-driven networking

Scrapy 是基于 Twisted 实现的,Twisted 是 Python 的一个非常流行的事件驱动型网络框架;它的并发是使用的是非阻塞的方式完成的,通过 aka asynchronous 实现的;

更多有关 Twisted 的介绍可以参考,