Python爬虫入门,快速抓取大规模数据(第六部分)

hilary0 2018-06-13

在前面的章节中,我们以尽量少的代码演示了爬虫的基本原理。如果只是需要抓取一些简单的数据,那么我们修改一下前面的代码就可以完成任务了。但是当我们需要完成一些复杂的大型抓取任务时,我们就需要考虑更多东西,例如爬虫的可扩展性,抓取效率等。

现在让我们再回顾一下我们抓取的过程:从待下载URL列表取出URL;构造和发送HTTP请求下载网页;解析网页提取数据,解析网页提取URL并加入待下载列表;存储从网页提取的数据。在这个过程中有很多地方是通用的,而对于具体抓取任务有关的只是网页数据和URL提取。因为通用代码部分可以重用,所以框架就诞生了。现在python下有很多爬虫框架,比较常用的是Scrapy。接下来的我们简单的介绍一下Scrapy的用法。

Scrapy框架介绍和安装

Scrapy是python开发的一个快速和高效的web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy被广泛的应用于于数据挖掘、监测和自动化测试。Scrapy的安装也非常容易,简单的运行运行pip install Scrapy,我们需要的开发环境就准备好了。

创建Scrapy项目

这里我们会用Scrapy框架重写我们前面的爬虫。在开始前我们需要创建一个新的Scrapy项目。假设我们的项目名叫Douban,运行scrapy startproject Douban。文件夹Douban被创建出来了,这个文件夹下包含了我们爬虫的基本框架。

这里有几个比较重要的概念:

  • Item代表了我们从网页中提取到的数据,我们提取出的数据会存放到一个Item对象中。
  • Spider处理抓取返回的网页,实现数据的提取。提取数据生成item对象并返回给框架。
  • Pipeline实现抓取数据存储。当Spider返回的Item对象,框架将会根据配置调用pipeline来存储数据。为什么要叫pipeline呢?因为我们可以实现多个数据存储方式,比如数据需要保存到数据库和文件,那我们就可以实现和配置两pipeline类,不同的存储方式依次调用。
  • Request代表一个下载请求,由下载URL生成。
  • Response代表一个下载结果,包含了抓取网页的内容。

Python爬虫入门,快速抓取大规模数据(第六部分)

创建Item类

我们使用Item类来对从网页中解析出的数据进行封装,方便在各个模块之间传递和做进一步处理。爬虫的Item类非常简单,直接继承scrapy的Item 类并定义相应的属性字段来对数据进行存储。每个字段类型为scrapy.Field(),可以用来存储任意类型的数据。 现在看看我们的Item类定:

Python爬虫入门,快速抓取大规模数据(第六部分)

创建Spider类

Spider类主要是用来解析数据的类,其包含了一些用于下载的初始URL和提取网页中的链接和数据的方法。所有的Spider都必须继承自scrapy.Spider类,并实现三个属性:

  • name: Spider的名字。
  • start_urls: 爬虫启动的url列表。
  • parse() : 解析抓取的网页内容, 每个url下载后会调用这个该函数提取数据(并生成返回item对象),以及提取和生成需要进一步处理的URL的Request对象。

Python爬虫入门,快速抓取大规模数据(第六部分)

创建pipeline类

Scrapy使用pipeline模块来保存数据的操作。也就是Spider类的parse()方法返回的Item对象将会传递给Pipeline中的类,由Pipeline来完成具体的保存工作。在创建的Scrapy项目时会自动创建了一个pipeline.py文件,它包含了一个默认的Pipeline类。

Pipeline类会在process_item()方法中处理数据,然后在结束时调用 close_spider()方法,因此我们需要这两个方法做相应的处理。

Python爬虫入门,快速抓取大规模数据(第六部分)

运行爬虫

在项目目录下,执行命令scrapy crawl Douban,我们可看到的爬虫开始爬取网页了。

总结

现在让我们回顾一下我们所有代码在Scrapy框架下是如何工作的:

  • 首先,Scrapy为Spider的start_urls属性中的每个URL创建scrapy.Request对象,并将parse()方法作为回调函数传递给了Request对象。
  • Request对象经过框架调度,执行下载后得到scrapy.http.Response对象,这个对象被传递给Spider的parse()方法解析。
  • Spider的parse()方法解析数据并返回Item对象,Item对象被传递给Pipeline对象的process_item()处理。
  • Pipeline的process_item()完成提取到的数据(Item对象)的存储或任何需要的处理。
  • 如果parse()方法解析出了新的URL并返回新的Request对象,在这个新的Request对象会重复上述步骤处理,从而实现连续的数据抓取。

往期文章:

Python爬虫入门,快速抓取大规模数据5

Python爬虫入门,快速抓取大规模数据4

Python爬虫入门,快速抓取大规模数据3

Python爬虫入门,快速抓取大规模数据2

Python爬虫入门,快速抓取大规模数据1

相关推荐