跟我学系列,走进Scrapy爬虫(三)初窥Scrapy

上一篇

跟我学系列,走进Scrapy爬虫(二)爬虫利器

本章工作任务

  • 任务1:为什么使用Scrapy

  • 任务2:安装和配置Scrapy

  • 任务3: Scrapy命令行工具

  • 任务4:编写第一个Scrapy爬虫

  • 本章技能目标及重难点

    技能点描述 级别
    1 为什么使用Scrapy?
    2 安装和配置Scrapy ★★
    3 Scrapy命令行工具 ★★★
    4 编写第一个Scrapy爬虫 ★★★

    注: “★”理解级别 “★★”掌握级别 “★★★”应用级别

    本章学习目标

    本章开始学习Scrapy爬虫框架,需要同学们理解为什么使用Scrapy,它的概念、特点。最主要的是需要大家学会如何建立一个简单的爬虫项目。

    本章学习建议

    本章适合有Python基础的学员学习。

    本章内容(学习活动)

    3.1为什么使用Scrapy?

    3.1.1 什么是Scrapy

    Scrapy 是一个为了爬取 站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。

    其最初是为了页面抓取 (更确切来说, 络抓取)所设计的, 也可以应用在获取 API 所返回的数据(例如 Amazon Associates Web Services ) 或者通用的 络爬虫。

    Scrapy其实是Search+Python。Scrapy 使用 Twisted这个异步 络库来处理 络通讯,架构清晰,并且包含了各种中间件接口,可以灵活的完成各种需求。

    3.1.2 Scrapy整体结构

    1、引擎(Scrapy Engine)

    用来处理整个系统的数据流处理,触发事务。

    2、调度器(Scheduler)

    用来接受引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回。

    3、下载器(Downloader)

    用于下载 页内容,并将 页内容返回给蜘蛛。

    4、蜘蛛(Spiders)

    蜘蛛是主要干活的,用它来制订特定域名或 页的解析规则。编写用于分析response并提取item(即获取到的item)或额外跟进的URL的类。 每个spider负责处理一个特定(或一些) 站。

    蜘蛛的整个抓取流程(周期)是这样的:

    1. 首先获取第一个URL的初始请求,当请求返回后调取一个回调函数。第一个请求是通过调用start_requests()方法。该方法默认从start_urls中的Url中生成请求,并执行解析来调用回调函数。

    2. 在回调函数中,你可以解析 页响应并返回项目对象和请求对象或两者的迭代。这些请求也将包含一个回调,然后被Scrapy下载,然后有指定的回调处理。

    3. 在回调函数中,你解析 站的内容,同程使用的是Xpath选择器(但是你也可以使用BeautifuSoup, lxml或其他任何你喜欢的程序),并生成解析的数据项。

    4. 最后,从蜘蛛返回的项目通常会进驻到项目管道。

    5、项目管道(Item Pipeline)

    主要责任是负责处理有蜘蛛从 页中抽取的项目,他的主要任务是清晰、验证和存储数据。当页面被蜘蛛解析后,将被发送到项目管道,并经过几个特定的次序处理数据。每个项目管道的组件都是有一个简单的方法组成的Python类。他们获取了项目并执行他们的方法,同时他们还需要确定的是是否需要在项目管道中继续执行下一步或是直接丢弃掉不处理。

    项目管道通常执行的过程有:

    1. 清洗HTML数据

    2. 验证解析到的数据(检查项目是否包含必要的字段)

    3. 检查是否是重复数据(如果重复就删除)

    4. 将解析到的数据存储到数据库中

    6、下载器中间件(Downloader Middlewares)

    位于Scrapy引擎和下载器之间的钩子框架,主要是处理Scrapy引擎与下载器之间的请求及响应。它提供了一个自定义的代码的方式来拓展Scrapy的功能。下载中间器是一个处理请求和响应的钩子框架。他是轻量级的,对Scrapy尽享全局控制的底层的系统。

    7、蜘蛛中间件(Spider Middlewares)

    介于Scrapy引擎和蜘蛛之间的钩子框架,主要工作是处理蜘蛛的响应输入和请求输出。它提供一个自定义代码的方式来拓展Scrapy的功能。蛛中间件是一个挂接到Scrapy的蜘蛛处理机制的框架,你可以插入自定义的代码来处理发送给蜘蛛的请求和返回蜘蛛获取的响应内容和项目。

    8、调度中间件(Scheduler Middlewares)

    介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。他提供了一个自定义的代码来拓展Scrapy的功能。

    3.1.3 数据处理流程

    Scrapy执行流程图

    如图3-1所示,显示的是Scrapy爬虫执行流程,绿线是数据流向,首先从初始URL开始,Scheduler会将其交给Downloader进行下载,下载之后会交给Spider进行分析,Spider分析出来的结果有两种:一种是需要进一步抓取的链接,例如之前分析的“下一页”的链接,这些东西会被传回Scheduler;另一种是需要保存的数据,它们则被送到Item Pipeline那里,那是对数据进行后期处理(详细分析、过滤、存储等)的地方。另外,在数据流动的通道里还可以安装各种中间件,进行必要的处理。

    Scrapy中的数据流由执行引擎控制,其过程如下:

    1. 引擎打开一个 站(open a domain),找到处理该 站的Spider并向该spider请求第一个要爬取的URL(s)。

    2. 引擎从Spider中获取到第一个要爬取的URL并在调度器(Scheduler)以Request调度。

    3. 引擎向调度器请求下一个要爬取的URL。

    4. 调度器返回下一个要爬取的URL给引擎,引擎将URL通过下载中间件(请求(request)方向)转发给下载器(Downloader)。

    5. 一旦页面下载完毕,下载器生成一个该页面的Response,并将其通过下载中间件(返回(response)方向)发送给引擎。

    6. 引擎从下载器中接收到Response并通过Spider中间件(输入方向)发送给Spider处理。

    7. Spider处理Response并返回爬取到的Item及(跟进的)新的Request给引擎。

    8. 引擎将(Spider返回的)爬取到的Item给Item Pipeline,将(Spider返回的)Request给调度器。

    9. (从第二步)重复直到调度器中没有更多地request,引擎关闭该 站。

    3.2安装和配置Scrapy

    3.2.1 安装Python

    如何安装Python呢?大家跟着我的步骤往下做哦。

    打开官
    http://www.python.org/downloads页面。

    Python官方 站下载页面

    页面上有两个版本3.5.2和2.7.12,目前最新的是3.5.2。当然Python3.5.2比Python2.7.12有功能上的拓展,但是由于现在行内的有些软件及环境还没有完全兼容Python3.5.2,故本书以Python2.7.12的语法技术讲解为主,兼顾Python3.5.2。这只是版本上的差异,大家不要纠结版本问题。

    1、安装2.7.12版本相关步骤

    (1)单击

    按钮后,页面变为下图3-3:

    Python官方 站下载python2.7.12

    33

    在上图1-5中的左下角有

    显示,表示正在下载2.7.12版本的python软件。

    (2)下载完毕后,点击右边的黑色三角形,出现下图:

    准备安装python2.7.12

    点击“打开”,则显示图2-4:

    安装python2.7.12进行中-1

    点击图1-7中的“运行”按钮,则出现下图2-5:

    安装python2.7.12进行中-2

    点击图3-6中的“Next”按钮,则出现下图:

    安装python2.7.12进行中-3

    图3-6表示选择安装python到本地磁盘的位置。若默认则为c:Python27文件夹。然后点击图3-6中的“Next”按钮,则出现下图:

    安装python2.7.12进行中-4

    该图3-7表示我们需要安装的python特征及用法,一般默认即可。然后点击该图3-7中的“Next”按钮,显示下图:

    安装python2.7.12进行中-5

    图3-8这个安装过程将持续几分钟,当安装无问题时,最后出现下图:

    安装python2.7.12完成图

    当出现图3-9时,表示python安装成功,此时点击图2-9中的“Finish”按钮即可。

    其实到这步,你可以点击你的电脑屏幕系统左下角的“开始”,弹出下图3-10:

    开始菜单图

    点击图3-10中的“所有程序”这栏,弹出本机内装的程序清单,找到自己安装的Python2.7,如下图3-11:

    本机安装软件程序图

    3.2.2安装配置Scrapy

    一、安装pywin32

    在windows下,必须安装pywin32,安装地址:
    https://sourceforge.net/projects/pywin32/files/pywin32/,显示如下图3-11所示。

    pywin32各版本界面图

    本次我们安装选择安装的是Build 220,点击进入该链接:
    https://sourceforge.net/projects/pywin32/files/pywin32/Build%20220/,显示如下图3-13所示。

    pywin3 220下载界面图

    32位操作系统的同学,点击
    pywin32-220.win32-py2.7.exe下载链接,64位操作系统的同学,点击
    pywin32-220.win-amd64-py2.7.exe下载链接。

    为什么要安装pywin32?因为在window环境中,Scrapy要调用Window的基础命令,需要win32api的支持,才能使用。

    下载完成后,直接双击安装即可,安装完毕之后验证:

    在python命令行下输入

    import win32com

    如果没有提示错误,则证明安装成功,如图3-14所示

    pywin32验证

    二、安装zope.interface

    可以使用pip和easy_install来安装zope.interface,操作方式如图3-15所示。

    zope.interface安装

    现在也有exe版本,链接为:
    https://pypi.python.org/pypi/zope.interface/4.1.0#downloads,显示如下图3-16所示。

    zope.interface安装包下载界面

    32位操作系统的同学,点击
    zope.interface-4.1.0.win32-py2.7.exe下载链接,64位操作系统的同学,点击
    zope.interface-4.1.0.win-amd64-py2.7.exe下载链接。

    下载完成后,直接双击安装即可,安装完毕之后验证:

    在python命令行下输入

    import zope.interface

    如果没有提示错误,则证明安装成功,如图2-17所示

    zope.interface验证

    三、安装pyOpenSSL

    在Windows下,是没有预装pyOpenSSL的,而在Linux下是已经安装好的。

    安装地址:
    https://launchpad.net/pyopenssl,界面显示如下,如图3-18所示。

    pyOpenSSL下载界面

    四、安装Scrapy

    终于轮到安装scrapy了,直接在cmd中输入easy_install scrapy回车即可。安装后在cmd命令行进行成功与否的验证如图3-19所示。

    Scrapy安装验证

    安装完成,开始使用吧!

    3.3为什么要使用命令行工具?

    3.2.1Scrapy命令行工具是什么

    Scrapy 是通过 scrapy 命令行工具进行控制的。 这里我们称之为 “Scrapy tool” 以用来和子命令进行区分。对于子命令,我们称为 “command” 或者 “Scrapy commands”。

    Scrapy tool 针对不同的目的提供了多个命令,每个命令支持不同的参数和选项。

    3.2.2默认的 Scrapy 项目结构

    在开始对命令行工具以及子命令的探索前,让我们首先了解一下 Scrapy 的项目的目录结构。

    虽然可以被修改,但所有的 Scrapy 项目默认有类似于下边的文件结构:

    scrapy.cfg

    myproject/

    —-__init__.py

    —-items.py

    middlewares.py

    —-pipelines.py

    —-settings.py

    —-spiders/

    ——–__init__.py

    ——–spider1.py

    ——–spider2.py

    ——– …

    1.scrapy.cfg

    存放的目录被认为是项目的根目录 。该文件中包含 python 模块名的字段定义了项目的设置。

    2. items.py

    该文件中包含了scrapy数据容器模型代码。

    Item 对象是种简单的容器,保存了爬取到得数据。其提供了类似于词典(dictionary-like)的API以及用于声明可用字段的简单语法。

    3. middlewares.py

    该文件中包含下载器中间件和爬虫中间件模型代码。

    下载器中间件是介于 Scrapy 的 request/response 处理的钩子框架。 是用于全局修改 Scrapy request 和 response 的一个轻量、底层的系统。

    爬虫中间件是介入到 Scrapy 的 spider 处理机制的钩子框架,您可以添加代码来处理发送给 Spiders 的 response 及 spider 产生的 item 和 request。。

    4.pipelines.py

    每个管道组件是实现了简单方法的 Python 类。他们接收到 Item 并通过它执行一些行为,同时也决定此 Item 是否继续通过后续的管道组件,或是被丢弃而不再进行处理。

    5. settings.py

    Scrapy 设定(settings)提供了定制 Scrapy 组件的方法。您可以控制包括核心(core),插件(extension),pipeline 及 spider 组件。

    3.2.3全局命令工具

    1.startproject

    ? 语法:scrapy startproject <project_name>

    ? 是否需要项目:no

    在 project_name 文件夹下创建一个名为 project_name 的 Scrapy 项目。

    例子,如图3-20所示。

    startproject创建项目

    该命令将会在 MyProject 目录中创建一个 Scrapy 项目。

    2.genspider

    ? 语法:scrapy genspider [-t template] <name> <domain>

    ? 是否需要项目:yes

    在当前项目中创建 spider。

    这仅仅是创建 spider 的一种快捷方法。该方法可以使用提前定义好的模板来生成 spider。您也可以自己创建 spider 的源码文件。

    查看spider模板,使用 scrapygenspider –l 命令,如图3-21所示。

    查看spider模板

    (1)basic

    默认模板,生成最基础的爬虫代码,如图3-22所示。

    查看spider模板

    (2)crawl

    (3)csvfeed

    (4)xmlfeed


    3.4编写第一个Scrapy爬虫

    本课程将带您完成下列任务:

    1. 创建一个 Scrapy 项目

    2. 定义提取的 Item

    3. 编写爬取 站的 spider 并提取 Item

    4. 编写 Item Pipeline 来存储提取到的 Item(即数据)

    3.4.1创建项目

    在开始爬取之前,您必须创建一个新的 Scrapy 项目。 进入您打算存储代码的目录中,运行下列命令:

    scrapy startproject tutorial

    该命令将会创建包含下列内容的 tutorial 目录:

    tutorial/

    -scrapy.cfg

    —-tutorial/

    ——–__init__.py

    ——–items.py

    ——–pipelines.py

    ——–settings.py

    ——–spiders/

    ————__init__.py

    ————…

    这些文件分别是:

    ? scrapy.cfg: 项目的配置文件

    ? tutorial/: 该项目的 python 模块。之后您将在此加入代码。

    ? tutorial/items.py: 项目中的 item 文件。

    ? tutorial/pipelines.py: 项目中的 pipelines 文件。

    ? tutorial/settings.py: 项目的设置文件。

    ? tutorial/spiders/: 放置 spider 代码的目录。

    3.4.2定义Item

    Item 是保存爬取到的数据的容器;其使用方法和 python 字典类似, 并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。

    类似在 ORM 中做的一样,您可以通过创建一个 scrapy.Item 类, 并且定义类型为 scrapy.Field 的类属性来定义一个 Item。 (如果不了解 ORM, 不用担心,您会发现这个步骤非常简单)

    items.py代码

    一开始这看起来可能有点复杂,但是通过定义 item, 您可以很方便的使用 Scrapy 的其他方法。而这些方法需要知道您的 item 的定义。

    3.4.3Spider爬虫

    Spider 是用户编写用于从单个 站(或者一些 站)爬取数据的类。

    其包含了一个用于下载的初始 URL,如何跟进 页中的链接以及如何分析页面中的内容, 提取生成 item 的方法。

    为了创建一个 Spider,您必须继承 scrapy.Spider 类, 且定义以下三个属性:

    ? name: 用于区别 Spider。 该名字必须是唯一的,您不可以为不同的 Spider 设定相同的名字。

    ? start_urls: 包含了 Spider 在启动时进行爬取的 url 列表。 因此,第一个被获取到的页面将是其中之一。 后续的 URL 则从初始的 URL 获取到的数据中提取。

    ? parse() 是 spider 的一个方法。 被调用时,每个初始 URL 完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成 item)以及生成需要进一步处理的 URL 的 `Request 对象。

    以下为我们的第一个 Spider 代码,保存在 tutorial/spiders 目录下的 dmoz_spider.py 文件中,如图3-24所示:

    demoz_spider.py代码

    3.4.4爬虫爬取

    进入项目的根目录,执行下列命令启动 spider:

    scrapy crawl dmoz

    crawl dmoz 启动用于爬取 dmoz.org 的 spider,您将得到类似的输出,如图3-25所示。

    dmoz爬虫运行情况

    查看包含 [dmoz] 的输出,可以看到输出的 log 中包含定义在 start_urls 的初始 URL,并且与 spider 中是一一对应的。在 log 中可以看到其没有指向其他页面( (referer:None) )。

    除此之外,更有趣的事情发生了。就像我们 parse 方法指定的那样,有两个包含 url 所对应的内容的文件被创建了: Book,Resources,如图3-26所示 。

    生成文件

    刚才发生了什么?Scrapy 为 Spider 的 start_urls 属性中的每个 URL 创建了 scrapy.Request 对象,并将 parse 方法作为回调函数(callback)赋值给了 Request。

    Request 对象经过调度,执行生成 scrapy.http.Response 对象并送回给 spider parse() 方法。

    3.4.5提取Item

    从 页中提取数据有很多方法。Scrapy 使用了一种基于 XPath 和 CSS 表达式机制: Scrapy Selectors。 关于 selector 和其他提取机制的信息请参考 Selector 文档。

    这里给出 XPath 表达式的例子及对应的含义:

    ? /html/head/title: 选择 HTML 文档中<head>标签内的<title>元素

    ? /html/head/title/text(): 选择上面提到的<title>元素的文字

    ? //td: 选择所有的<td>元素

    ? //div[@class=”mine”]: 选择所有具有属性的 div 元素

    上边仅仅是几个简单的 XPath 例子,XPath 实际上要比这远远强大的多。

    为了配合 XPath,Scrapy 除了提供了 Selector 之外,还提供了方法来避免每次从 response 中提取数据时生成selector 的麻烦。

    Selector 有四个基本的方法:

    ? xpath(): 传入 xpath 表达式,返回该表达式所对应的所有节点的 selector list 列表 。

    ? css(): 传入 CSS 表达式,返回该表达式所对应的所有节点的 selector list 列表.

    ? extract(): 序列化该节点为 unicode 字符串并返回 list。

    ? re(): 根据传入的正则表达式对数据进行提取,返回 unicode 字符串 list 列表。

    在 Shell 中尝试 Selector 选择器

    为了介绍 Selector 的使用方法,接下来我们将要使用内置的 Scrapy shell。

    您需要进入项目的根目录,执行下列命令来启动 shell:

    scrapy shell http://www.dmoz.org/Computers/Programming/Languages/Python/Books/

    注解:当您在终端运行 Scrapy 时,请一定记得给 url 地址加上引 ,否则包含参数的 url(例如 & 字符)会导致 Scrapy 运行失败。

    shell 的输出,如图3-27所示。

    生成文件

    当 shell 载入后,您将得到一个包含 response 数据的本地 response 变量。输入 response.body 将输出 response 的包体,输出 response.headers 可以看到 response 的包头。

    更为重要的是,当输入 response.selector 时, 您将获取到一个可以用于查询返回数据的 selector(选择器), 以及映射到 response.selector.xpath() 、response.selector.css() 的 快捷方法(shortcut): response.xpath() 和 response.css() 。

    同时,shell 根据 response 提前初始化了变量 sel 。该 selector 根据 response 的类型自动选择最合适的分析规则(XML vs HTML)。

    让我们来试试,如图3-28所示

    提取数据

    现在,我们来尝试从这些页面中提取些有用的数据。

    您可以在终端中输入 response.body 来观察 HTML 源码并确定合适的 XPath 表达式。不过,这任务非常无聊且不易。您可以考虑使用 Firefox 的 Firebug 扩展来使得工作更为轻松。详情请参考 使用 Firebug 进行爬取和借助 Firefox 来爬取。

    在查看了 页的源码后,您会发现 站的信息是被包含在 第二个 <ul> 元素中。

    我们可以通过这段代码选择该页面中 站列表里所有 <li> 元素,如图3-30所示。

    提取数据

    站的描述,如图3-31所示。

    提取数据

    站的标题,如图3-32所示。

    提取数据

    站的链接,如图3-33所示。

    提取数据

    之前提到过,每个.xpath()调用返回 selector 组成的 list,因此我们可以拼接更多的.xpath()来进一步获取某个节点。我们将在下边使用这样的特性,如图3-34所示。

    xpath()进一步操作

    在我们的 spider 中加入这段代码,如图3-35所示。

    spider代码

    现在尝试再次爬取 dmoz.org,您将看到爬取到的 站信息被成功输出,使用命令,scrapy crawl dmoz。

    3.4.6使用Item

    Item 对象是自定义的 python 字典。您可以使用标准的字典语法来获取到其每个字段的值。(字段即是我们之前用 Field 赋值的属性),代码如图3-36所示

    使用Item

    一般来说,Spider 将会将爬取到的数据以 Item 对象返回。所以为了将爬取的数据返回,我们最终的代码将是如图3-37所示。

    Item代码

    现在对 dmoz.org 进行爬取将会产生 DmozItem 对象,输出结果如图3-38所示。

    Item运行结果

    3.4.7保存爬取到的数据

    最简单存储爬取的数据的方式是使用 Feed exports,使用命令,scrapy crawl dmoz -o items.json。

    该命令将采用 JSON 格式对爬取的数据进行序列化,生成 items.json 文件。

    在类似本篇教程里这样小规模的项目中,这种存储方式已经足够。 如果需要对爬取到的 item 做更多更为复杂的操作,您可以编写 Item Pipeline 。 类似于我们在创建项目时对 Item 做的,用于您编写自己的 tutorial/pipelines.py 也被创建。 不过如果您仅仅想要保存 item,您不需要实现任何的 pipeline。

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2017年1月1日
    下一篇 2017年1月1日

    相关推荐