在之前的文章中,我们已经学习了如何使用Scrapy
框架来编写爬虫项目,那么具体Scrapy
框架中底层是如何架构的呢?Scrapy
主要拥有哪些组件,爬虫具体的实现过程又是怎么样的呢?
为了更深入的了解Scrapy
的相关只是,我们需要对Scrapy
的架构以及Scrapy
中常见的组件进行了解,并熟悉Scrapy
爬虫项目的工作流程
架构初识
要充分的理解和使用scrapy
,那么就不得不了解以下scrapy
的核心架构是怎么样的,如图:
从图中我们可以看到,Scrapy
中组件主要包括:
- Scrapy引擎
- 调度器
- 下载器
- 下载中间件
- 蜘蛛(也叫做爬虫,一个Scrapy项目下可能会有多个Spiders爬虫文件)
- 爬虫中间件
- 实体管道
其中Scrapy引擎为整个架构的核心。调度器、实体管道、下载器和蜘蛛等组件都通过Scrapy引擎来调控。在Scrapy引擎和下载器之间,可以通过一个叫下载中间件的组件进行信息的传递,在下载中间件中,可以插入一些自定义的代码来轻松扩展Scrapy的功能。Scrapy引擎和蜘蛛之间,也可以通过一个叫爬虫中间件的组件进行爬虫与Scrapy引擎的信息传递,也同样可以插入一些自定义的代码来轻松扩展Scrapy的功能。在一个Scrapy项目中可以存在多个爬虫文件,在运行的时候,可以指定运行某一个爬虫文件。通过Scrapy引擎可以调度下载器进行下载互联网中的网页数据,以传递给蜘蛛(爬虫)文件进行对应的处理
常用组件详解
Scrapy引擎
Scrapy引擎是整个Scrapy
架构的核心,负责控制整个数据处理流程,以及出发一些事物处理。Scrapy引擎与调度器、实体管道、中间件、下载器、蜘蛛等组件都有关系,Scrapy引擎处于整个Scrapy
框架的中心的位置,对各项组件进行控制及协调
调度器
调度器主要实现存储待爬取的网页,并确定这些网址的优先级,决定下一次爬取哪个网址等。我们可以把调度器的存储结构看成一个优先队列,调度器会从引擎中接收request请求并存入优先队列中,在队列中可能会有多个待爬取的网址,但是这些网址各自具有一定的优先级,同时调度器也会过滤掉一些重复的网址,避免重复爬取
下载器
下载器主要实现对网络上要爬取的网页资源进行高速下载,由于该组件需要通过网络进行大量数据的传输,所以该组件的压力负担一般会比其他的组件重。下载器下载了对应的网页资源后,会将这些数据传递给Scrapy引擎,再由Scrapy引擎传递给对应的爬虫进行处理
下载中间件
下载中间件是处于下载器与Scrapy引擎之间的一个特定的组件,主要用于对下载器和Scrapy引擎之间的通信进行处理,在下载中间件中,可以加入自定义代码,轻松地实现Scrapy功能的扩展,我们下载中间件加入的自定义代码,会在Scrapy引擎与下载器通信的时候调用
蜘蛛
蜘蛛组件,也叫做爬虫组件,该组件是Scrapy框架中爬虫实现的核心。在一个Scrapy项目中,可以有多个蜘蛛,每个蜘蛛可以负责一个或多个特定的网站。蜘蛛组件主要负责接收Scrapy引擎中的response响应,在接收了response响应之后,蜘蛛会对这些response响应进行分析处理,然后可以提取对应的关注的数据,也可以提取出接下来需要处理的新网址等信息
爬虫中间件
爬虫中间件是处于Scrapy引擎与爬虫中间件之间的一个特定的组件,主要用于对爬虫组件和Scrapy引擎之间的通信进行处理。同样,在爬虫中间件可以加入一些自定义代码,轻松的实现Scrapy功能的扩展。在爬虫中间件中加入的自定义代码,会在Scrapy引擎与爬虫组件之间通信的时候调用
实体管道
实体管道主要用于接收从蜘蛛组件中提取出来的项目(Item),接收后,会对这些Item进行对应的处理,常见的处理主要有:清洗,验证,存储到数据库中等
Scrapy工作流
我们已经知道了Scrapy
框架中主要有哪些组件,以及各项组件的具体作用有哪些,那么在运行Scrapy
爬虫项目的时候,各项数据处理在组件中又是怎么进行的呢?这些组件会如何配合呢?下面请看Scrapy
数据处理流程图,如下:
首先,Scrapy引擎会将爬虫文件中设置的要爬取的起始网址(默认在start_urls
属性中设置)传递到调度器中。随后,依次进行图中的1~13的过程。
第1步:过程1中,主要将下一次要爬取的网址传递给Scrapy引擎,调度器是一个优先队列,里面可能存储着多个要爬取的网址(当然也可能只有一个网址),调度器会根据各网址的优先级分析出下一次要爬取的网址,然后再传递给Scrapy引擎
第2步:Scrapy引擎接收到过程1中传过来的网址之后,过程2Scrapy引擎主要将网址传递给下载中间件
第3步:下载中间件接收到Scrapy引擎传递过来的网址之后,过程3中下载中间件会将对应的网址传递给下载器
第4步:然后,下载器接收到对应要下载的网址,然后过程4会向互联网中对应的网址发送request请求,进行网页的下载
第5步:互联网中对应的网址接收到request请求之后,会有相应的response响应,随后在过程5中将响应返回给下载器
第6步:下载器接收到响应之后,即完成了对应网页的下载,随后过程6会将对应的响应传递给下载中间件
第7步:下载中间件接收到对应响应之后,会与Scrapy引擎进行通信,过程7会将对应的response响应传递给Scrapy引擎
第8步:Scrapy引擎接收到response响应之后,过程8Scrapy引擎会将response响应信息传递给爬虫中间件
第9步:爬虫中间件接收到对应响应之后,过程9爬虫中间件会将响应传递给对应的爬虫进行处理
第10步:爬虫进行处理之后,大致会有两方面的信息:提取出来的数据和新的请求信息。然后过程10爬虫会将处理后的信息传递给爬虫中间件。
第11步:爬虫中间件接收到对应信息后,过程11会将对应信息传递给Scrapy引擎
第12步:Scrapy引擎接收到爬虫处理后的信息之后,会同时进行过程12和过程13。在过程12中,Scrapy引擎会将提取出来的项目实体(item)传递给实体管道(item pipeline),由实体管道对提取出来的信息进行进一步处理:过程13中,Scrapy引擎会将爬虫处理后得到的新的请求信息传递给调度器,由调度器进行进一步网址的调度
随后,再重复执行第1 ~ 12步,即过程1 ~ 13,一直到调度器中没有网址调度或者异常退出为止