Scrapy 框架
(本文仅用作个人记录)
- Scrapy框架是用纯python实现一个为了爬去网站数据,提取结构性数据而编写的应用框架,用途非常广泛。
- Scrapy 使用了 Twisted['twɪstɪd](其主要对手是Tornado)异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求。
Scrapy 架构图
Scrapy Engine(引擎): 负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。
Scheduler(调度器): 它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。
Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,
Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器),
Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方.
Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。
Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)
Scrapy的运行流程:
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.管道``调度器:好的,现在就做!
(只有当调度器中不存在任何request时,整个程序才会停止,对于下载失败的URL,Scrapy会重新下载。)
制作Scapy爬虫的步骤:
新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
明确目标 (编写items.py):明确你想要抓取的目标
制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页
存储内容 (pipelines.py):设计管道存储爬取内容
Scrapy实例:
我们要爬取的网站为:http://quotes.toscrape.com/,这是一个英文版的名人名言网站。如下图所示。
1.新建项目:
进入任意一个文件夹,直接使用scrapy命令生成项目:
scrapy stratproject tutorial
命令将会创建一个tutorial 文件夹,文件夹结构如下图所示。
----scrapy.cfg #Scrapy部署时的配置文件
----tutorial
---------__init__.py #里面内容为空,但必须要有,不可删除
---------items.py #Items的定义,定义爬取的数据结构
---------middlewares.py #定义爬取时的中间件
---------pipelines.py #定义数据管道
---------settings.py #配置文件
---------spiders文件夹 #放置Spiders的文件夹
进入tutorial文件夹,生成爬虫:
scrapy genspider quotes quotes.toscrape.com
(genspider 第一个参数是Spider的名称,第二个参数是指定爬取域的范围)
执行完毕之后,spiders文件夹下多了一个quotes.py
2.明确目标:创建Item
打开 items.py
我们要抓取该网站的 名言文本,作者以及标签。
所以items.py 修改如下:
注意定义的类名为 QuotesItem,且需要继承scrapy.Item类。
3.制作爬虫
打开spiders 文件夹下的quotes.py
初始内容如下:
name:每个项目唯一的名字
allowed_domains :允许爬取的域名,如果初始或者后续的请求链接不是这个域名下的,则请求链接会被过滤掉
start_urls :起始url,第一个请求链接
parse() :解析方法,当下载器完成请求之后,返回的响应就是该方法的response 参数。该方法负责解析返回的响应、提取数据或者生成下一步请求。
根据对网页结构的分析,我们使用css选择器提取数据。结果如下。
next 是用来获取下一页的链接。
对于后续请求,我们构造请求需要用到 scrapy.Request。这里传递两个参数,url和callback。
url是请求链接,callback 是回调函数。当指定了该回调函数的请求完成之后,获取到相应,引擎会将该响应作为参数传递给这个回调函数。回调函数进行解析或者生成下一步请求。这里的回调函数仍然使用parse进行解析。这样爬虫就进入了一个循环。
最后使用yield 返回该请求:yield scrapy.Request(url=url, callback=self.parse)
理论上,此爬虫程序已经可以完成爬取,但是我们没有将爬取结果保存下来,爬取内容只会在终端显示。我们需要把爬取结果保存到数据库。
4.存储结果
如果只是保存到文件,我们可以不需要编写任何文件,只需要执行爬虫程序时 在后面加上
- o quotes.json
完整命令:scrapy crwal quotes -o quotes.json
那么在tutorial 文件夹下就多处一个 quotes.json 文件。
如果保存到数据库,就需要编写pipelines.py 文件。
"""
Item Pipeline 为项目管道,当Item生成后,它会自动被送到ItemPipeline进行处理,
常用来:
清理HTml数据
验证爬取数据
查重去重
保存到数据库
"""
实现Item Pipeline很简单,只需实现 process_item(self, item, spider) 方法即可。Item Pipeline启动之后会自动调用这个方法。process_item 方法必须返回包含数据的字典或者Item对象,或者抛出 DropItem 异常。
接下来我们实现 筛选掉text长度大于100的Item,并将结果保存到MySQL数据库。
TutorialPipelin 类的 process_item 方法已经实现了筛选的功能。
要实现保存到数据的功能,我们还需要自己定义一个类---MySQLPipeline 类名可以随意取。
定义好这两个类之后,需要在settings.py 中使用他们。
启用 ITEM_PIPELINES 配置,注意要类名一致。键值为优先级,数字越小优先级越高。
之后,命令行执行 scrapy crawl quotes,可以看到一些scrapy的执行情况。
最后打开数据库,看一下保存情况。需要提前建好表。
至此,我们就已经完成了Quotes网站的Scrapy抓取的简单入门。
PS:
from scrapy.utils.project import get_project_settings
self.host = get_project_settings.get("MYSQL_HOST")
这个方法也可以从settings.py里面获取全局配置信息。