什么是 Scrapy?
Python 写的开源爬虫框架,快速、简单的方式构建爬虫,从网站上提取你所需要的数据。
-
优点:
功能非常强大的爬虫框架,不仅能便捷地构建request,还有强大的selector能够方便地解析response,最受欢迎的还是它的性能,既抓取和解析的速度,它的downloader是多线程的,request是异步调度和处理的。这两点使它的爬取速度非常之快。另外还有内置的logging,exception,shell等模块,为爬取工作带来了很多便利。 -
缺点:
scrapy是封装起来的框架,他包含了下载器,解析器,日志及异常处理,基于多线程, twisted的方式处理,对于固定单个网站的爬取开发,有优势,但是对于多网站爬取100个网站,并发及分布式处理方面,不够灵活,不便调整与括展。
如何安装和使用的问题,请参考 官方网站https://scrapy.org/ 学习,源码地址:https://github.com/scrapy/scrapy
Scrapy有什么作用?
用于数据挖掘、监测和自动化测试。
资料:https://xie.infoq.cn/article/f3505fba11fe9f9615cacc6f6
为什么有这篇文章?业界很多开源的爬虫框架都是模仿和参考 Scrapy 的思想和架构实现的,如果想深入学习爬虫,研读 Scrapy 的源码还是很有必要的。
架构概览
介绍一下 Scrapy 的整体架构,从宏观层面上学习一下 Scrapy 运行的流程。
使用 Scrapy 开发一个爬虫非常简单,只需以下几步:
- 使用 scrapy startproject 命令创建一个爬虫模板,或自己按模板编写爬虫代码
- 定义一个爬虫类,并继承 scrapy.Spider,然后重写 parse 方法
- parse 方法里编写网页解析逻辑,以及抓取路径
- 使用 scrapy runspider <spider_file.py> 运行这个爬虫
使用 Scrapy 编写简单的几行代码,就能采集到一个网站页面的数据,非常方便。
Scrapy 到底是如何帮助我们工作的呢?
架构
Scrapy 主要包含以下五大核心模块:
- Scrapy Engine:核心引擎,负责控制和调度各个组件,保证数据流转;
- Scheduler:负责管理任务、过滤任务、输出任务的调度器,存储、去重任务都在此控制;
- Downloader:下载器,负责在网络上下载数据,输入待下载的 URL,输出下载结果;
- Spiders:我们自己编写的爬虫逻辑,定义抓取意图;
- Item Pipeline:负责输出结构化数据,可自定义格式和输出的位置;
观察仔细还可以看到还有2个模块:
- Downloader middlewares:介于引擎和下载器之间,可以在网页在下载前、后进行逻辑处理;
- Spider middlewares:介于引擎和爬虫之间,在向爬虫输入下载结果前,和爬虫输出请求 / 数据后进行逻辑处理;
运行流程
Scrapy 内部采集流程是如何流转的?各个模块是如何交互协作,来完成整个抓取任务?
Scrapy 运行时的数据流转大概是这样的:
- 引擎从自定义爬虫中获取初始化请求(也叫种子 URL);
- 引擎把该请求放入调度器中,同时调度器向引擎获取待下载的请求;
- 调度器把待下载的请求发给引擎;
- 引擎发送请求给下载器,中间会经过一系列下载器中间件;
- 这个请求通过下载器下载完成后,生成一个响应对象,返回给引擎,这中间会再次经过一系列下载器中间件;
- 引擎接收到下载器返回的响应后,发送给爬虫,中间会经过一系列爬虫中间件,最后执行爬虫自定义的解析逻辑;
- 爬虫执行完自定义的解析逻辑后,生成结果对象或新的请求对象给引擎,再次经过一系列爬虫中间件;
- 引擎把爬虫返回的结果对象交由结果处理器处理,把新的请求通过引擎再交给调度器;
- 重复执行 1-8,直到调度器中没有新的请求处理,任务结束;
核心模块交互图:
(图中 Scrapyer 模块,也是 Scrapy 的一个核心模块,但官方的架构图没有展示出来。这个模块其实是处于 Engine、Spiders、Pipeline 之间,是连接这 3 个模块的桥梁)
核心类图
没有样式的黑色文字是类的核心属性;标有黄色样式的高亮文字是类的核心方法;
读源码的过程中,可以针对这些核心属性和方法重点关注。
Scrapy 涉及到的组件主要包括以下这些:
五大核心类: Scrapy Engine、Scheduler、Downloader、Spiders、Item Pipeline;
四个中间件管理器类:DownloaderMiddlewareManager、SpiderMiddlewareManager、ItemPipelineMiddlewareManager、ExtensionManager;
其他辅助类:Request、Response、Selector;