使用Python的Scrapy框架编写web爬虫的简单示例

669次阅读  |  发布于5年以前

在这个教材中,我们假定你已经安装了Scrapy。假如你没有安装,你可以参考这个安装指南

我们将会用开放目录项目(dmoz)作为我们例子去抓取。

这个教材将会带你走过下面这几个方面:

Scrapy由Python写成。假如你刚刚接触Python这门语言,你可能想要了解这门语言起,怎么最好的利用这门语言。假如你已经熟悉其它类似的语言,想要快速地学习Python,我们推荐这种深入方式学习Python。假如你是新手,想从开始使用Python学习,可以尝试去看看非程序员Python资源列表

创造一个项目

在你要抓取之前,首先要建立一个新的Scrapy项目。然后进去你的存放代码目录,执行如下命令。


    scrapy startproject tutorial

它将会创建如下的向导目录:

复制代码 代码如下:

tutorial/
scrapy.cfg
tutorial/
init.py
items.py
pipelines.py
settings.py
spiders/
init.py
...

这是一些基本信息:

定义我们的Item

Items是装载我们抓取数据的容器。它们工作像简单的Python字典,它提供更多的保护,比如对未定义的字段提供填充功能防止出错。

它们通过创建scrapy.item.Item类来声明并定义它们的属性作为scrapy.item.Field 对象,就像是一个对象关系映射(假如你不熟悉ORMs,你将会看见它是一个简单的任务).

我们将需要的item模块化,来控制从demoz.org网站获取的数据,比如我们将要去抓取网站的名字,url和描述信息。我们定义这三种属性的域。我们编辑items.py文件,它在向导目录中。我们Item类看起来像这样。


    from scrapy.item import Item, Field

    class DmozItem(Item):
     title = Field()
     link = Field()
     desc = Field()

这个看起来复杂的,但是定义这些item能让你用其他Scrapy组件的时候知道你的item到底是什么

我们第一个Spider

Spiders是用户写的类,它用来去抓取一个网站的信息(或者一组网站) 。
我们定义一个初始化的URLs列表去下载,如何跟踪链接,如何去解析这些页面的内容去提取 items.创建一个Spider,你必须是scrapy.spider.BaseSpider的子类, 并定义三个主要的,强制性的属性。

[名字](http://doc.scrapy.org/en/0.16/topics/spiders.html#scrapy.spider.BaseSpider.name): Spider的标识. 它必须是唯一的, 那就是说,你不能在不同的Spiders中设置相同的名字。

[开始链接](http://doc.scrapy.org/en/0.16/topics/spiders.html#scrapy.spider.BaseSpider.start_urls):Spider将会去爬这些URLs的列表。所以刚开始的下载页面将要包含在这些列表中。其他子URL将会从这些起始URL中继承性生成。

[parse() ](http://doc.scrapy.org/en/0.16/topics/spiders.html#scrapy.spider.BaseSpider.parse)是spider的一个方法, 调用时候传入从每一个URL传回的[Response](http://doc.scrapy.org/en/0.16/topics/request-response.html#scrapy.http.Response)对象作为参数。response是方法的唯一参数。

这个方法负责解析response数据和提出抓取的数据(作为抓取的items),跟踪URLs

parse()方法负责处理response和返回抓取数据(作为Item对象) 和跟踪更多的URLs(作为request的对象)

这是我们的第一个Spider的代码;它保存在moz/spiders文件夹中,被命名为dmoz_spider.py:


    from scrapy.spider import BaseSpider

    class DmozSpider(BaseSpider):
     name = "dmoz"
     allowed_domains = ["dmoz.org"]
     start_urls = [
      "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
      "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
     ]

     def parse(self, response):
      filename = response.url.split("/")[-2]
      open(filename, 'wb').write(response.body)

为了使你的spider工作, 到项目的顶级目录让后运行:


    scrapy crawl dmoz

crawl dmoz命令使spider去爬dmoz.org网站的信息。你将会得到如下类似的信息:


    2008-08-20 03:51:13-0300 [scrapy] INFO: Started project: dmoz
    2008-08-20 03:51:13-0300 [tutorial] INFO: Enabled extensions: ...
    2008-08-20 03:51:13-0300 [tutorial] INFO: Enabled downloader middlewares: ...
    2008-08-20 03:51:13-0300 [tutorial] INFO: Enabled spider middlewares: ...
    2008-08-20 03:51:13-0300 [tutorial] INFO: Enabled item pipelines: ...
    2008-08-20 03:51:14-0300 [dmoz] INFO: Spider opened
    2008-08-20 03:51:14-0300 [dmoz] DEBUG: Crawled <http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: <None>)
    2008-08-20 03:51:14-0300 [dmoz] DEBUG: Crawled <http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: <None>)
    2008-08-20 03:51:14-0300 [dmoz] INFO: Spider closed (finished)

注意那些行包含[dmoz], 它和我们的spider相关。你能够看见每行初始化的URL日志信息。因为这些URLs是起始页面,所以他们没有引用referrers。 所以在每行的末尾部门,你能看见(referer: ).

但是有趣的是,在我们的parse方法作用下,两个文件被创建: Books and Resources, 它保航两个URLs的内容
刚刚发生了什么事情?

Scrapy为每一个start_urls创建一个scrapy.http.Request对象,并将爬虫的parse 方法指定为回调函数。

这些Request首先被调度,然后被执行,之后通过parse()方法,将scrapy.http.Response对象被返回,结果也被反馈给爬虫。

提取Items
选择器介绍

我们有多种方式去提取网页中数据。Scrapy 使用的是XPath表达式,通常叫做XPath selectors。如果想了解更多关于选择器和提取数据的机制,可以看看如下教程XPath selectors documentation.

这里有一些表达式的例子和它们相关的含义: