Scrapy框架介绍
scrapy是一个基于Twisted的异步处理框架,是纯Python实现的爬虫框架。
(注:Twisted是用Python实现的基于事件驱动的网络引擎框架,Twisted支持许多常见的传输及应用层协议,包括TCP、UDP、SSL/TLS、HTTP、IMAP、SSH、IRC以及FTP。就像Python一样,Twisted也具有“内置电池”(batteries-included)的特点。Twisted对于其支持的所有协议都带有客户端和服务器实现,同时附带有基于命令行的工具,使得配置和部署产品级的Twisted应用变得非常方便。)
1. 框架介绍
它可以分为以下几个部分:
- 引擎(Scrapy)
用来处理整个系统的数据流处理, 触发事务(框架核心) - 项目(Item)
它定义了爬取结果的数据结构,爬取的数据会被赋值成该item对象 - 调度器(Scheduler)
用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址 - 下载器(Downloader)
用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的) - 爬虫(Spiders)
其内定义了爬取的逻辑和网页的解析规则,它主要负责解析响应并生成提取结果和新的请求 - 项目管道(Pipeline)
负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。主要任务是清洗、验证和存储数据 - 下载器中间件(Downloader Middlewares)
位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。 - 爬虫中间件(Spider Middlewares)
介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。 - 调度中间件(Scheduler Middewares)
介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。
2.数据流
scrapy中的数据流由引擎控制,数据流的过程如下。
(1)Engine首先打开一个网站,找到处理该网站的Spider,并向该Spider请求第一个要爬取的URL。
(2)Engine从Spider中获取到第一个要爬取的URL,并通过Scheduler以Request的形式调度
(3)Engine向Scheduler请求下一个要爬取的URL
(4)Scheduler返回下一个要爬取的URL给Engine,Engine将URL通过DownLoader Middlewares转发给Downloader下载
(5)一旦页面下载完成,Downloader生成该页面的Response,并将其通过Downloader Middlewares发送给Engine
(6)Engine从下载器中接收到Response,并将其通过Spider Middlewares发送给Spider处理。
(7) Spider处理Response,并返回爬取到的Item及新的Request给Engine
(8)Engine将Spider返回的Item给Item Pipeline,将新的Request给Scheduler
(9)重复第(2)步到第(8)步,直到Scheduler中没有更多的Request,Engine关闭该网站,爬取结束
3.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也会重新下载。)
4.制作 Scrapy 爬虫 一共需要4步:
新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
明确目标 (编写items.py):明确你想要抓取的目标
- 制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页
- 存储内容 (pipelines.py):设计管道存储爬取内容
5.项目结构
项目文件结构如下
scrapy.cfg
project/
__init__.py
items.py
pipelines.py
settings.py
middlewares.py
spiders/
__init__.py
spider1.py
spider2.py
...
Scrapy入门
1.创建一个项目,项目文件可以直接用scrapy命令生成,命令如下所示:
scrapy startproject tutorial
这个命令可以在任意文件夹运行。会创建一个名为tutorial的文件夹,文件夹结构如下:
scrapy.cfg #Scrapy部署时的配置文件
tutorial/ #项目的模块,需要从这里引入
__init__.py
items.py #Items的定义,定义爬取的数据结构
middlewares.py #Middlewares的定义,定义爬取时的中间件
pipelines.py #Pipelines的定义,定义数据管道
settings.py #配置文件
spiders/ #放置Spiders的文件夹
__init.py__
2.创建Spider
Scrapy用它来从网页里爬取内容,并解析抓取的结果。不过这个类必须继承Scrapy提供的Spider类scrapy.Spider,还要定义Spider的名称和起始请求,以及怎样处理爬取后的结果的方法。
使用如下命令创建一个名为Quotes的Spider
scraoy genspider qoutes qoutes.toscrapy.com
第一个参数是Spider的名称,第二个参数是网站域名。
爬虫中有三个属性——name,allowed_domails和start_urls,还有一个方法parse。
name:它是每个项目唯一的名字,用来区分不同的Spider
allowed_domails:它是允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,则请求链接会被过滤掉
start_urls:它包含了Spider在启动时爬取的url列表,初始请求是由它来定义的
parse:它是Spider的一个方法。默认情况下,被调用时start_urls里面的链接构成的请求完成下载执行后,返回的响应就会作为唯一的参数传递给这个函数。该方法负责解析返回的响应,提取数据或者进一步生成要处理的请求。
3.创建itesm
Item是保存爬取诗句的容器,它的使用方法和字典类似。
创建item需要继承scrapy.Item类,并且定义类型为scrapy.Field的字段
Selector的用法
Scrapy提供了自己的数据提取方法,即Selector(选择器)。Selector是基于lxml来构建的,支持Xpath选择器、CSS选择器以及正则表达式。
例:
name = node.xpath(”./h3/text()”).extract
scrapy爬取到的为xpath对象,extarct()将xpath对象序列化为unicode字符串并返回list。
1.直接使用
from scrapy import Selector
title = selector.xpath('//title/text()').extract_first()
这里没有在Scrapy框架中运行,而是把Scrapy中的Selector单独拿出来使用了。构造时传入text参数,就生成了一个Selector选择器对象。
2.Scrapy shell
借助Scrapy来模拟scrapy的请求过程。
scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html
我们就进入到了Scrapy shell模式。这个过程就是Scrapy发起一次请求,请求URL就是刚才命令行下输入的URL。
我们可以在命令行模式下输入命令调用对象的一些操作方法。
Spider的用法
1.Spider的运行流程
Spider要做的事就是如下两件:
- 定义爬取网站的动作
分析爬取下来的网页
对于Spider类来说,整个爬取循环的过程如下所述
以初始的URL初始化Request,并设置回调函数。当该Request成功请求并返回时,Response生成并作为参数传给该回调函数。
- 在回调函数内分析返回的网页内容。返回结果有两种形式。一种是解析到的有效结果返回字典或Item对象,它们可以经过处理后(或直接)保存。另一种是解析得到下一个(如下一页)链接,可以利用此链接构造Request并设置新的回调函数,返回Request等待后续调度
- 如果返回的是字典或Item对象,我们可通过Feed Exports等组件将返回结果存入到文件。如果设置了Pipeline的话,我们可以使用Pipeline处理(如过滤、修正)并保存
- 如果返回的是Request,那么Request执行成功得到Response之后,Response会被传递给Request中定义的回调函数,在回调函数中我们可以再次使用选择器来分析新得到的网页内容,并根据分析的数据生成Item
2.Spider类分析
我们定义的Spider是继承自scrapy.spiders.Spider。
scrapy.spiders.Spider这个类提供了start_requests()方法的默认实现,读取并请求start_urls属性,并根据返回的结果调用parse()方法解析结果。
基础属性解释:
- name:爬虫名称,是定义Spider名字的字符串。
- allowed_domains:允许爬取的域名,是可选配置
- start_urls:起始URL列表,当我们没有实现start_requests()方法时,默认会从这个列表开始抓取
- custom_settings:它是一个字典,是专属于本Spider的配置,此设置会覆盖项目全局的设置。此设置必须在初始化前更新,必须定义成类变量。
crawler:它是由from_crawler()方法设置的,代表的是本Spider类对应的Crawler对象。Crawler对象包含了很多项目组件,利用它我们可以获取项目的一些配置信息,如最常见的获取项目的设置信息,即Settings
Spider的常用方法:
- start_requests():此方法用于生成初始请求,它必须返回一个可迭代对象。此方法会默认使用start_urls里面的URL来构造Request,而且Request是GET请求方式。如果我们想在启动时以POST方式访问某个站点,可以直接重写这个方法,发送POST请求时使用FormRequest即可
- parse():当Response没有指定回调函数时,该方法会默认被调用。它负责处理Response,处理返回结果,并从中提取出想要的数据和下一步的请求,然后返回。该方法需要返回一个包含Request或Item的可迭代对象。
- closed():当Spider关闭时,该方法会调用时,在这里一般会定义释放资源的一些操作或其他收尾操作。
Downloader Middleware的用法
Downloader Middleware即下载中间件,它是处于Scrapy的Request和Response之间的处理模块。
Downloader Middleware在整个架构中起作用的位置是以下两个:
- 在Scheduler调度处队列的Request发送给Doanloader下载之前,也就是我们可以在Request执行下载之前对其进行修改
在下载后生成的Response的Response发送给Spider之前,也就是我们可以生成Response被Spider解析之前对其进行修改。
1.使用说明
Scrapy提供了一个设置变量DOWNLOADER_MIDDLEWARES,我们直接修改这个变量就可以添加自己定义的Downloader Middleware,以及禁用DOWNLOADER_MIDDLEWARES_BASE里面定义的Downloader Middleware。
2.核心方法
核心方法如下三个:
- process_request(request, spider)
- process_response(request, response, spider)
- process_exception(request, exception, spider)
我们只需要实现至少一个方法就可以定义Downloader Middleware。
- process_request(request, spider)
持续更新中。。。