array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 Scrapy框架流程图详解 - 爱码网

(一)、Scrapy框架介绍:

我们写一个爬虫,需要做很多事情,比如:发送网络请求、数据解析、数据存储、反爬虫、反反爬虫(更换ip代理、设置请求头等)、异步请求等。这些事情在我们每一次写爬虫代码的时候都要自己从零开始写的话,比较浪费时间。因此 Scrapy 把一些基础的东西封装好了,在它上面写爬虫可以变的更加高效。

(二)、Scrapy架构图及各个组件:

流程图(1):

Scrapy框架流程图详解
流程图(2):Scrapy框架流程图详解
Scrapy框架主要由六大组件组成,它们分别是调试器(Scheduler)、下载器(Downloader)、爬虫(Spider)、中间件(Middleware)、实体管道(Item Pipeline)和Scrapy引擎(Scrapy Engine)。

2.1 Scrapy Engine(引擎):Scrapy引擎是整个框架的核心。它用来控制调试器、下载器、爬虫。它就相当于计算机中的CPU,控制着整个流程。
2.2 Spider(爬虫):发送需要爬取的链接给引擎,最后引擎再把其他模块中请求回来的数据再发送给爬虫,爬虫就会去解析想要的数据。爬取链接以及解析页面中的数据都是由自己来写的。
2.3 Scheduler(调度器):它负责引擎发过来的请求,按照一定的方式进行排序和整理,负责调度请求的顺序等。
2.4 Downloader(下载器):它负责引擎发过来的下载请求,然后去网络上下载对应的数据后,再把这个数据交还给引擎。
2.5 Item Pipeline(实体管道):负责将Spider(爬虫)传递过来的数据进行保存。具体保存在哪里应该看我们自己的需要。
2.6 Middleware(中间件):负责对Request对象和Response对象进行处理(见流程图一)

中间件又分为两部分:

1.Downloader Middlewares(下载中间件):它是拓展下载器和引擎之间的通信功能的中间件。比如说,在下载器执行之前可以在中间件进行一些操作:设置一些代理ip、设置一些请求头等。
2.Spider Middlewares(爬虫中间件):它是拓展爬虫和引擎之间的通信功能的中间件。同样的它也可以做一些操作。

(三)、Scrapy流程

1: 首先 先从Spider发送一个请求,初始化了一个Resquest对象,并且设置了回调函数(也就是创建Scrapy项目后的def parse(self, response)),把请求传给引擎。
2: 引擎收到请求后,并不会把请求马上发送出去,而是传给了调度器。调度器接受到引擎发过来的Requser请求后,把Request对象按照一定的排序算法存储到它里面的一个队列当中。
3: 接下来引擎会不断的从调度器当中取出已经处理好的Request
4: 当引擎拿到Request后,再把这个请求扔给下载器。
5: 下载器拿到请求后,按照下载中间件中的设置去互联网上面下载request请求。下载好数据后再把数据传送给引擎。
6: 引擎拿到数据之后,再把这个数据(也就是response)通过爬虫中间件返回给Spider。并把response作为参数传递给第一步设置好的回调函数。
7: 爬虫拿到数据之后(这个爬虫是由我们自己写),经过分析,把不需要的数据剔除掉,把需要的数据提取出来(使用xpath、BeautifulSoup、正则)。接下来再把提取出来的数据扔给引擎。
8: 引擎拿到数据之后,把这个数据扔给实体管道(如果这时还有其他的Requset,会重复3-8这个过程,直到获取完所有的自己想要的信息)。管道中的代码也是由我们自己来写,该怎么存储,存储到哪里去等。

以上步骤做完后,就实现了爬虫。

下面是从其他博主那里看到的一个算是小故事吧,觉得很形象的把整个流程给描述了出来。

1.引擎:Hi!Spider, 你要处理哪一个网站?

2.Spider:老大要我处理xxxx.com。

3.引擎:你把第一个需要处理的URL给我吧。

4.Spider:给你,第一个URL是xxxxxxx.com。

5.引擎:Hi!调度器,我这有request请求你帮我排序入队一下。

6.调度器:好的,正在处理你等一下。

7.引擎:Hi!调度器,把你处理好的request请求给我。

8.调度器:给你,这是我处理好的request

9.引擎:Hi!下载器,你按照老大的下载中间件的设置帮我下载一下这个request请求

10.下载器:好的!给你,这是下载好的东西。(如果失败:sorry,这个request下载失败了。然后引擎告诉调度器,这个request下载失败了,你记录一下,我们待会儿再下载)

11.引擎:Hi!Spider,这是下载好的东西,并且已经按照老大的下载中间件处理过了,你自己处理一***意!这儿responses默认是交给def
parse()这个函数处理的)

12.Spider:(处理完毕数据之后对于需要跟进的URL),Hi!引擎,我这里有两个结果,这个是我需要跟进的URL,还有这个是我获取到的Item数据。

13.引擎:Hi !管道 我这儿有个item你帮我处理一下!调度器!这是需要跟进URL你帮我处理下。然后从第四步开始循环,直到获取完老大需要全部信息。
14.管道“调度器:好的,现在就做!

自己刚学Scrapy不久,便乘热打铁巩固一下并加上自己的一些理解,有不足之处请各位大佬帮忙斧正。

相关文章: