1. Scrapy
1.1 Scrapy框架的安装
Scrapy是一个十分强大的爬虫框架,依赖的库比较多,至少需要依赖的库有Twisted 、lxml和pyOpenSSL。在不同的平台环境下,它所依赖的库也各不相同,所以在安装之前,最好确保把一些基本库安装好。
通过pip安装:pip install scrapy
如果出现如下错误:
这是安装Twisted导致的这个错误的发生的,需要从非官方版本下载twisted并安装:
https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
下载对应版本后,通过pip安装:
pip install Twisted-19.2.0-cp36-cp36m-win_amd64.whl
Twisted是用Python实现的基于事件驱动的网络引擎框架,Twisted支持许多常见的传输及应用层协议,包括TCP、UDP、SSL/TLS、HTTP、IMAP、SSH、IRC以及FTP。scrapy是基于twisted实现的。
成功安装twisted后,再通过pip install scrap即可成功安装scrapy。
1.2 Scrapy框架基本使用
第一步:创建项目
CMD进入需要放置项目的目录 输入:
# DoubanBook代表项目的名字
用pycharm打开可以看到如下目录结构:
第二步:创建一个爬虫
cd DoubanBook
scrapy genspider doubanbook book.douban.com
其中doubanbook是爬虫的名字,http://book.douban.com代表爬虫爬取url。
执行成功后,可以看到spiders目录下新生成的文件:
打开doubanbook.py文件,可以看到scrapy框架生成的基本爬虫模板,里面定义了爬虫的名称,爬取起始url,还有一个需要完善的解析方法。
第三步:实现爬虫
先简单尝试一下把parse方法里的pass去掉,打印网页源码:
def
第四步:运行爬虫
通过下面命令运行爬虫:
# doubanbook就是第二步创建爬虫时定义的爬虫名称
这时会出现403错误
这是因为豆瓣网站检测了请求是不是由浏览器发起的,不是的话会被拒绝访问,所以要让爬虫模拟浏览器请求。
修改settings.py配置文件,配置请求头:
# Override the default request headers:
再次运行爬虫,就能正常打印出网页源码。
scrapy从创建项目到运行爬虫的基本流程就是这样,详细内容在后面具体介绍。
1.3 Scrapy基本原理
scrapy架构如图所示:
- Scrapy Engine: scrapy引擎,负责Spiders、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等等。
- Scheduler(调度器): 它负责接受引擎发送过来的requests请求,并按照一定的方式进行整理排列、入队,等待Scrapy Engine(引擎)来请求时,交给引擎。
- Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spiders来处理,
- Spiders:它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器),
- Item Pipeline:它负责处理Spiders中获取到的Item,并进行处理,比如去重,持久化存储(存数据库,写入文件,总之就是保存数据用的)
- Downloader Middlewares(下载中间件):可以当作是一个可以自定义扩展下载功能的组件。
- Spider Middlewares(Spider中间件):可以理解为是一个可以自定扩展和操作引擎和Spiders中间‘通信‘的功能组件(比如进入Spiders的Responses;和从Spiders出去的Requests)
根据scrapy框架的架构,建立一个项目之后:
第一件事情是在items.py文件中定义一些字段,这些字段用来临时存储你需要保存的数据。方便后面保存数据到其他地方,比如数据库 或者 本地文本之类的。
第二件事情在spiders文件夹中编写自己的爬虫。
第三件事情在pipelines.py中存储自己的数据。
第四件事情,不是非做不可的,settings.py文件 并不是一定要编辑的,只有有需要的时候才会编辑。SpiderMiddleware和DownloaderMiddleware也是在有需要的情况下进行修改。
1.4 Scrapy中items的用法
在items中定义爬取内容,如下所示:
import
1.5 Scrapy中spiders的用法
spider中通过解析请求的页面,最后构造一个item并返回。解析可以使用xpath进行解析,也可以使用Beautiful Soup等第三方库解析。
import
1.6 Scrapy中Item Pipeline的用法
页面解析后得到item之后,通过item pipeline进行后处理,一般是存入数据库或写入文件。
把数据存入数据库,需要使用到pymysql、pymongo等操作数据库的第三方库,通过pip安装:
pip install pymysql
pip install pymongo
下面通过MySQL演示具体使用:
import
然后取消settings中的ITEM_PIPELINES注释,数字代表优先级,当有多个item_pipelines的时候起作用。
# Configure item pipelines
这样再执行scrapy crawl doubanbook启动爬虫,数据就会保存到数据库中。
2.使用scrapy-redis实现分布式爬虫
Scrapy 是一个通用的爬虫框架,但是不支持分布式,Scrapy-redis是为了更方便地实现Scrapy分布式爬取,而提供了一些以redis为基础的组件。
2.1 scrapy-redis安装
需要安装reids和scrapy_redis库。
pip install redis
pip install scrapy_redis
2.2 scrapy-redis基本原理
Scrapy-Redis分布式策略:
- Master端(核心服务器) :搭建一个Redis数据库,负责url指纹判重、Request的分配,以及数据的存储
- Slaver端(爬虫程序执行端) :负责执行爬虫程序,运行过程中提交新的Request给Master
- Scrapy-Reids 就是将Scrapy原本在内存中处理的 调度(就是一个队列Queue)、去重这两个操作通过Redis来实现。
- 多个Scrapy在采集同一个站点时会使用相同的redis key(可以理解为队列)添加Request 获取Request 去重Request,这样所有的spider不会进行重复采集。
- Redis是原子性的,一个Request要么被处理 要么没被处理,不存在第三可能。
2.3 scrapy-redis实例
2.3.1 items.py
定义两个item,一个是待爬取的每本书的url,一个是每本书的具体内容。
# -*- coding: utf-8 -*-
2.3.2 spiders
实现两个spider,一个用来获取每本书的url,存入redis,框架实现去重,爬取队列等。另一个用来爬取每本书的具体内容,从redis中读取url进行爬取。
master端spider:返回MasterRedisItem
import
client端spider:返回DangdangItem,其中redis_key = 'dangdang:start_urls',和下面pipelines对应一致。
# -*- coding: utf-8 -*-
2.3.3 pipelines.py
处理url的redis缓存和最终数据保存到数据库。
# -*- coding: utf-8 -*-
2.3.4 middlewares.py
# -*- coding: utf-8 -*-
2.3.5 settings.py
# -*- coding: utf-8 -*-
运行master端开始获取url存入redis,client端可以开启多个同时进行爬取,这样就实现了spider的并行。
scrapy crawl dangmaster # 开启一个
scrapy crawl dangdang # 可以开启多个
3.反爬措施
代码还没敲完就被封的豆瓣。
3.1 代理ip的使用
许多网站也做了许多反爬措施,其中爬虫访问过于频繁直接封ip地址的方法被许多网站采用,代理ip便可以防止这种情况出现。
scrapy框架在middlewares里设置代理ip。
def
3.2 cookies池的使用
有的网站不登录直接爬取会有一些弊端,弊端主要有以下两点。
- 设置了登录限制的页面无法爬取。如某论坛设置了登录才可查看资源,某博客设置了登录才可查看全文等,这些页面都需要登录账号才可以查看和爬取。
- 一些页面和接口虽然可以直接请求,但是请求一旦频繁,访问就容易被限制或者IP直接被封,但是登录之后就不会出现这样的问题,因此登录之后被反爬的可能性更低。
所以可以搭建一个cookies池来模拟登录。
GitHub地址:
https:// github.com/stormstone/S piderSSS
References
- 崔庆才的个人博客
- 廖雪峰的官方网站
- Urllib模块的使用
- Requests官方文档
- Xpath教程
- selenium官网
- selenium-python文档
- pyquery官网
- 使用 scrapy-redis实现分布式爬虫