背景
使用Scrapy分布式爬取知乎所有用户个人信息!
项目地址 爬取知乎所有用户
大规模抓取静态网页Scrapy绝对是利器!当然也可以使用requests库来自己实现,但是要自己写过滤器等组件,既然有现成的轮子并且还是很好的轮子就没必要再造一个了!
image
使用Scrapy时单一进程抓取的时候速度太慢,可以使用多进程,但是如果觉得还是慢,那么我们可以使用基于redis的分布式抓取,几台电脑或则服务器同时抓取来提升抓取效率,详情看下一篇!
文章结构
Scrapy 简介
Scrapy 是怎么工作的
Scrapy 实例
遇到的问题
Scrapy 简介
An open source and collaborative framework for extracting the data you need from websites. In a fast, simple, yet extensible way这是官方对scrapy的描述. 从这里我们可以看到几个关键词 fast , simple , extensible 这也是我们使用scrapy的几个需求出发点.我们启动好了项目后建了APP后只需要简单的更改和设置就能完成一个网站的爬取,对于新手也是非常友好的!这使得开发更加快速便捷.整个过程中我们只要专注于如何提取数据就好了!Scrapy框架使用了异步的模式,可以加快我们的下载速度,并且内置了去重的过滤器,这也简化了我们的开发过程. 我们这里提供了部署工具Scrapyd这让我们在部署的时候更方便.
详细信息可以移步官方网站Scrapy,文档在这里中文官方文档, 英文官方文档
说了那么多,其实就想表达一件事:使用Scrapy,网络爬虫不再困难! 既然Scrapy有那么多好处,那么我们先来了解下它的原理吧
Scrapy 是怎么工作的
引用网上的一张图来说明整个工作原理:
scrapy
可以看到整个Scrapy 有几个组件:
Spider(蜘蛛),Scheduler(调度器),Downloader(下载器),Item Pipeline(管道),Engine(引擎),Downloader Middlewares(下载中间件),Spider Middlewares(蜘蛛中间件).我们引用网上的一个小故事来说明各个组件之间的关系:
代码写好,程序开始运行...
引擎:Hi!Spider, 你要处理哪一个网站?
Spider:老大要我处理xxxx.com。
引擎:你把第一个需要处理的URL给我吧。
Spider:给你,第一个URL是xxxxxxx.com。
引擎:Hi!调度器,我这有request请求你帮我排序入队一下(这里的是request对象,中间包含了url,下载工作是交给下载器来处理的)。
调度器:好的,正在处理你等一下。
引擎:Hi!调度器,把你处理好的request请求给我。
调度器:给你,这是我处理好的request
引擎:Hi!下载器,你按照老大的下载中间件的设置帮我下载一下这个request请求
下载器:好的!给你,这是下载好的东西。(如果失败:sorry,这个request下载失败了。然后引擎告诉调度器,这个request下载失败了,你记录一下,我们待会儿再下载)
引擎:Hi!Spider,这是下载好的东西,并且已经按照老大的下载中间件处理过了,你自己处理一下(注意!这儿responses默认是交给def parse()这个函数处理的)
Spider:(处理完毕数据之后对于需要跟进的URL),Hi!引擎,我这里有两个结果,这个是我需要跟进的URL,还有这个是我获取到的Item数据。
引擎:Hi !管道 我这儿有个item你帮我处理一下!调度器!这是需要跟进URL你帮我处理下。然后从第四步开始循环,直到获取完老大需要全部信息。
管道调度器:好的,现在就做!
注意!只有当调度器中不存在任何request了,整个程序才会停止,(也就是说,对于下载失败的URL,Scrapy也会重新下载。)
通过这个小故事可以清楚的知道--spider获取连接交给调度器,调度器来去重后将下载连接交给下载器,下载器下载好了东西交给蜘蛛,然后需要的内容就交给管道,如果还有连接就再次交给调度器...
总结一下:
引擎(Scrapy): 用来处理整个系统的数据流处理, 触发事务(框架核心)
调度器(Scheduler): 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
下载器(Downloader): 用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
爬虫(Spiders): 爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
项目管道(Pipeline): 负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
下载器中间件(Downloader Middlewares): 位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。
爬虫中间件(Spider Middlewares): 介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。
调度中间件(Scheduler Middewares): 介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。
理解了整个工作原理我们开始动手! 还是那句话:如果你想了解一个框架,Just Do It ! 这里我们使用一个爬取知乎所有用户的爬虫来演示!
Scrapy 实例
思路分析:
抛开框架我们来分析下我们爬取的原理: 我们从一个关注的人开始,获取这个关注的人的信息并储存下来,然后获取这个关注的人的的关注的人和粉丝,再去获取关注人的人的信息并存储循环往复下去就实现了从一个人开始层层抓取下去.来张图-借鉴传销图:
爬取原理
当然如果一个人没有关注人没有粉丝那就算了,放过他们!我们可以利用递归的思想来实现这个思路
环境配置:
推荐使用虚拟环境来创建环境 虚拟环境教程在这里
python3, Scrapy, mongodb, pymongo, redis, python_redis, Scrapyd, scrapyd-client
安装过程中可能出现报错,我把我安装过程中报错的信息以及解决方法写到了文章的结尾
1.安装Scrapy系列以及连接数据库的包
$ pip install Scrapy Scrapyd scrapyd-client pymongo redis python_redis
如果你没有安装pip 请按照下面的方法来安装:
sudo python get-pip.py install
2.安装mongodb:
这里使用官方的教程:官方教程
选择自己的系统查看教程进行选择教程安装
image
创建项目
以上环境安装好里以后,在终端下输入:
$ scrapy startproject zhihuScrapy
image
创建爬虫
scrapy genspider zhihu www.zhihu.com
第三个参数为爬虫名字,第四个为爬取的范围
image
这是整个项目的结构
image
在pycharm中打开项目(选择你喜欢的编辑器,这里我们使用pycharm)