Scrapy框架分析

      Scrapy框架分析

1 简介

  Scrapy是用Python开发的一个开源的Web爬虫框架,可用于快速抓取Web站点并从页面中高效提取结构化的数据。Scrapy可广泛应用于数据挖掘、信息处理或存储历史数据等一系列的程序中。提供了多种类型爬虫的基类,如BaseSpider、SitemapSpider等。其最初是为了页面抓取(更确切来说,网络抓取)所设计的,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services)或者通用的网络爬虫。
  Scrapy基于事件驱动网络框架 Twisted 编写,因而它采用的是基于事件驱动的设计,这种设计模型有利于与使用者进行交互,由于Scrapy并发性的考虑,因而被设计成非阻塞(异步)的实现。
  Scrapy爬虫框架共包括7各部分,称之为“5+2”结构。主体结构包括Scrapy Engine、Spiders、Downloader、Item Pipelines和Scheduler模块,同时在Engine和Downloader、Spiders之间有两个中间件模块,分别是Downloader Middleware和Spider Middleware模块。具体的框架如图1-1 所示

这里写图片描述
图1-1 Scrapy爬虫框架

2 核心部件

2.1 Spider

  Spider是Scrapy用户编写用于分析response并提取item(即获取到的item)或额外跟进的URL的类。用来向整个框架提供要访问的url链接,同时还要解析出从网页中获得的url内容。同时还定义了如何爬取某些网站,包括爬取的动作(例如是否跟进链接)以及如何从网页的内容中提取结构化的数据。简言之为:
  (1)解析Downloader返回的响应(Response)
  (2) 产生爬取项(scraped item)
  (3) 产生额外的爬取请求(Request)
  对spider来说,爬取的循环结构如下:
  (1) 以初始的URL初始化Request,并设置回调函数。当该request下载完毕并返回时,将生成response,并作为参数传给该回调函数。
  spider中初始的request是通过调用start_requests()来获取的。start_requests()读取start_urls中的URL,并以parse为回调函数生成Request。
  (2) 在回调函数内分析返回的网页内容,返回Item对象或者Request或者一个包括二者的可迭代容器。返回的Request对象之后会经过Scrapy处理,下载相应的内容,并调用设置的callback函数(函数可相同)。
  (3) 在回调函数内,可以使用选择器(Selectors)(也可以使用BeautifulSoup, lxml 或者想用的任何解析器)来分析网页内容,并根据分析的数据生成item。
  (4) 最后,由spider返回的item将被存到数据库(由某些Item Pipeline处理)或使用Feed exports存入到文件中。

2.2 Item pipelines

  Item pipelines负责处理被spider提取出来的item。典型的处理有清理、验证及持久化(例如存取到数据库中)。
  (1) 以流水线方式处理Spider产生的爬取项。Spider产生了对网页爬取之后的信息,信息在网页中经过一个又一个功能模块,功能模块以流水线的形式处理。
  (2) 由一组操作顺序组成,类似流水线,每个操作是一个Item Pipeline类型
  (3) 可能操作包括:清理、检验和查重爬取项中的HTML数据、将数据存储到数据库需要用户编写配置代码,完全由用户来定义的。具体是想要将数据存储在数据库中,还是简单的对数据进行清洗,都是要在该模块中实现。
  Item Pipelines有一些典型的应用如下:
  (1) 清理HTML数据
  (2) 验证爬取的数据(检查含item包含某些字段)
  (3) 查重(并丢弃)
  (4) 将爬取结果保存到数据库中

2.3 Downloader middlewares

  下载器中间件是介于Scrapy的request/response处理的钩子框架。是用于全局修改Scrapy request和response的一个轻量、底层的系统。当用户通过scheduler向网站提交一个访问请求,如访问百度的网站,用户可编写代码在downloader middleware中将用户的访问请求拦截下来,把他修改为google或其他等。一般情况如果用户不需要修改request,response等指令时,用户可以不修改该指令。

2.4 Spider Middleware

  Spider中间件是在引擎及Spider之间的特定钩子(specific hook),处理spider的输入(response)和输出(items及requests)。其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能。
目的:对请求和爬取项的再处理
功能:修改、丢弃、新增请求或爬取项

2.5 Scrapy Engine

  它是整个框架的核心引擎,控制各模块数据流,不间断从Scheduler处获得爬取请求,并将请求发送给downloader模块。框架的执行过程是从spider向engine发送第一个请求开始,到获得内容并将内容处理放到item pipelines为止。
并根据相应动作发生时触发事件,这些动作包括Request和Response等事件。用户不需要更改。

2.6 Downloader

  通过用户提交的请求下载网页。功能比较单一,只是获得一个请求,并且向网络中提交这个请求,最终获得返回的相关内容。用户不需要修改。

2.7 Scheduler

  Scheduler是对所有的请求进行调度管理的模块。对网络中同时有很多的爬取请求,设定其访问优先级,保持系统正常快速运行。用户不需要更改。

3 数据流

这里写图片描述 图3-1 数据流向

  按照架构图的序号,数据流转大概是这样的(对应上图编号):
  (1) 引擎从自定义爬虫中获取初始化请求(也叫种子URL);
  (2) 引擎把该请求放入调度器中,同时引擎向调度器获取一个待下载的请求(这两部是异步执行的);
  (3) 调度器返回给引擎一个待下载的请求;
  (4) 引擎发送请求给下载器,中间会经过一系列下载器中间件;
  (5) 这个请求通过下载器下载完成后,生成一个响应对象,返回给引擎,这中间会再次经过一系列下载器中间件;
  (6) 引擎接收到下载返回的响应对象后,然后发送给爬虫,执行自定义爬虫逻辑,中间会经过一系列爬虫中间件;
  (7) 爬虫执行对应的回调方法,处理这个响应,完成用户逻辑后,会生成结果对象或新的请求对象给引擎,再次经过一系列爬虫中间件;
  (8) 引擎把爬虫返回的结果对象交由结果处理器处理,把新的请求对象通过引擎再交给调度器;
  (9) 从1开始重复执行,直到调度器中没有新的请求处理;
  归纳以上数据流转,可以将框架的数据流路径分为三大类:分别如下:
  (1) Spider通过Engine到达Scheduler(即1->2),其中Engine通过spider中获取爬虫请求,称之为Request。Engine将请求转发给Scheduler模块,Scheduler负责对爬取请求进行调度。
  (2) 从Scheduler模块通过Engine模块到Downloader模块,并且最终到达Spider模块(即3->4->5->6)。首先Engine模块从Scheduler模块获取下一个要爬取的网络请求,这时的网络请求是真实的要去网络爬取的请求,获取请求后通过中间件发送给Downloader模块,Downloader通过这些请求连接互联网,爬取相关网页,爬取网页后形成对象,称之为Response,然后再通过中间件和Engine将Response发送到Spider
  (3) 从Spider模块通过Engine模块到达Item Pipelines和Scheduler模块(即7->8)。首先Spider处理从Downloader爬取的响应,也就是爬取的相关内容,产生两个数据类型,一个内容是爬取项Scrapy Item、另一个是新的爬取请求(在网站上获取一个网页后,网页中有其他的链接也是我们十分感兴趣的,可以在spider中增加相关的功能,对新的链接发起再次爬取)。然后发送给Engine模块,Engine收到两类数据后将其中的item发送给Item Pipelines,将其中的Request发送给Scheduler进行调度,为再次启动爬虫请求提供新的数据来源。

4 框架设计

  Scrapy基于事件驱动网络框架 Twisted 编写,因而它采用的是基于事件驱动的设计,这种设计模型有利于与使用者进行交互
  由于Scrapy并发性的考虑,因而被设计成非阻塞(异步)的实现。

5 实例介绍

  Scrapy Tutorial
  在抓取之前, 你需要新建一个Scrapy工程. 进入一个你想用来保存代码的目录,然后执行:
  $ scrapy startproject tutorial
  这个命令会在当前目录下创建一个新目录 tutorial, 它的结构如下:
  .x000D├── scrapy.cfg_x000D_└── tutorial_x000D_ ├── init.py_x000D_ ├── items.py_x000D_ ├── pipelines.py_x000D_ ├── settings.py_x000D_ └── spiders_x000D_ └── init.py
  这些文件主要是:
  scrapy.cfg: 项目配置文件
  tutorial/: 项目python模块, 之后您将在此加入代码
  tutorial/items.py: 项目items文件
  tutorial/pipelines.py: 项目管道文件
  tutorial/settings.py: 项目配置文件
  tutorial/spiders: 放置spider的目录

5.1. 定义Item

  Items是将要装载抓取的数据的容器,它工作方式像 python 里面的字典,但它提供更多的保护,比如对未定义的字段填充以防止拼写错误。
  通过创建scrapy.Item类, 并且定义类型为 scrapy.Field 的类属性来声明一个Item。我们通过将需要的item模型化,来控制从 dmoz.org 获得的站点数据,比如我们要获得站点的名字,url 和网站描述,我们定义这三种属性的域。在 tutorial 目录下的 items.py 文件编辑
  from scrapy.item import Item, Field_x000D__x000D_class DmozItem(Item): # define the fields for your item here like:x000D name = Field()x000D description = Field()x000D url = Field()

5.2. 编写Spider

  Spider 是用户编写的类, 用于从一个域(或域组)中抓取信息, 定义了用于下载的URL的初步列表, 如何跟踪链接,以及如何来解析这些网页的内容用于提取items。
  要建立一个 Spider,继承 scrapy.Spider 基类,并确定三个主要的、强制的属性:
  name:爬虫的识别名,它必须是唯一的,在不同的爬虫中你必须定义不同的名字.
  start_urls:包含了Spider在启动时进行爬取的url列表。因此,第一个被获取到的页面将是其中之一。后续的URL则从初始的URL获取到的数据中提取。我们可以利用正则表达式定义和过滤需要进行跟进的链接。
  parse():是spider的一个方法。被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。
  这个方法负责解析返回的数据、匹配抓取的数据(解析为 item )并跟踪更多的 URL。
  在 /tutorial/tutorial/spiders 目录下创建 dmoz_spider.py
  import scrapy_x000D_class DmozSpider(scrapy.Spider):x000D name = “dmoz”x000D allowed_domains = [“dmoz.org”]x000D start_urls = [x000Dhttp://www.dmoz.org/Computers/Programming/Languages/Python/Books/“,x000Dhttp://www.dmoz.org/Computers/Programming/Languages/Python/Resources/x000D ]x000D__x000D def parse(self, response):x000D filename = response.url.split(“/”)[-2]x000D with open(filename, ‘wb’) as f:x000D f.write(response.body)

5.3. 爬取

  当前项目结构
  ├── scrapy.cfg_x000D_└── tutorial_x000D_ ├── init.py_x000D_ ├── items.py_x000D_ ├── pipelines.py_x000D_ ├── settings.py_x000D_ └── spiders_x000D_ ├── init.py_x000D_ └── dmoz_spider.py
  到项目根目录, 然后运行命令:
  $ scrapy crawl dmoz

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值