Python网络爬虫实战之十一:Scrapy爬虫框架入门介绍

96
麦典威
2018.08.14 09:37* 字数 2225

目录:Python网络爬虫实战系列

正文:

一、Scrapy简介

Scrapy是一个高级的Python爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫数据保存到csv、json等文件中。它能我们更好的完成爬虫任务,自己写Python爬虫程序好比孤军奋战,而使用了Scrapy就好比手底下有了千军万马。

scrapy.png
  • Scrapy Engine(Scrapy核心) 负责数据流在各个组件之间的流。
  • Spiders(爬虫)发出Requests请求,经由Scrapy Engine(Scrapy核心) 交给Scheduler(调度器),Downloader(下载器)Scheduler(调度器) 获得Requests请求,然后根据Requests请求,从网络下载数据。
  • Downloader(下载器)的Responses响应再传递给Spiders进行分析。根据需求提取出Items,交给Item Pipeline进行下载。Spiders和Item Pipeline是需要用户根据响应的需求进行编写的。
  • 除此之外,还有两个中间件,Downloaders Mddlewares和Spider Middlewares,这两个中间件为用户提供方面,通过插入自定义代码扩展Scrapy的功能,例如去重等。

二、安装Scrapy

方法一,pip install scrapy

方法二,在http://www.lfd.uci.edu/~gohlke/pythonlibs/下载好对应自己Python版本的库,然后通过pip install XX库名 或 python setup.py install 安装。
安装Scrapy需要的库有:wheel、lxml、Twisted、Scrapy、pywin32

三、第一个Scrapy爬虫

1、创建项目

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

scrapy startproject tutorial

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


scrapy2.jpg
  • scrapy.cfg: 项目的配置文件
  • tutorial/: 该项目的python模块。之后您将在此加入代码。
  • tutorial/items.py: 项目中的item文件.
  • tutorial/middlewares.py:项目中的中间件
  • tutorial/pipelines.py: 项目中的pipelines文件.
  • tutorial/settings.py: 项目的设置文件.
  • tutorial/spiders/: 放置spider代码的目录.

2、编写Spider

Spider是用户编写用于从单个网站(或者一些网站)爬取数据的类,创建一个Spider,必须继承 scrapy.Spider 类, 且定义以下三个属性:name、start_urls、parse()

tutorial/spiders 目录下的新建 csdn_spider.py 文件,代码如下:

import scrapy


class CsdnSpider(scrapy.Spider):
    name = "csdn"
    allowed_domains = ["csdn.net"]
    start_urls = [
        "https://blog.csdn.net/jiangwei0910410003/article/details/79436956",
        "https://blog.csdn.net/M7720EIoSi6oA9/article/details/81463841"
    ]

    def parse(self, response):
        filename = "D:/DataguruPyhton/PythonSpider/images/" + response.url.split("/")[-1] + ".txt"
        with open(filename, 'wb') as f:
            f.write(response.body)
  • name: 用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。
  • start_urls: 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。
  • parse() 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。

3、爬取

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

scrapy crawl csdn

运行结果是生成了两个文件 79436956.txt 和 81463841.txt

刚才发生了什么?

Scrapy为Spider的 start_urls 属性中的每个URL创建了 scrapy.Request 对象,并将 parse 方法作为回调函数(callback)赋值给了Request。
Request对象经过调度,执行生成 scrapy.http.Response 对象并送回给spider parse() 方法。

四、第二个Scrapy爬虫

1、Scrapy Selectors机制

从网页中提取数据有很多方法,Scrapy使用了一种基于 XPath 和 CSS 表达式机制: Scrapy Selectors 。

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

  • /html/head/title: 选择HTML文档中 <head> 标签内的 <title> 元素
  • /html/head/title/text(): 选择上面提到的 <title> 元素的文字
  • //td: 选择所有的 td 元素
  • //div[@class="mine"]: 选择所有具有 class="mine" 属性的 div 元素

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

2、在Shell中尝试Selector选择器

为了配合XPath,Scrapy除了提供了 Selector 之外,还提供了方法来避免每次从response中提取数据时生成selector的麻烦。Selector有四个基本的方法(点击相应的方法可以看到详细的API文档):

  • xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表 。
  • css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表.
  • extract(): 序列化该节点为unicode字符串并返回list。
  • re(): 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。

为了介绍Selector的使用方法,接下来我们将要使用内置的 Scrapy shell 。Scrapy Shell需要您预装好IPython(一个扩展的Python终端)。

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

scrapy shell "https://blog.csdn.net/jiangwei0910410003/article/details/79436956"

观察终端的输出信息。

当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)。

在Shell中尝试如下操作:

In [1]: response.xpath('//title')
Out[1]: [<Selector xpath='//title' data=u'<title>Open Directory - Computers: Progr'>]

In [2]: response.xpath('//title').extract()
Out[2]: [u'<title>Open Directory - Computers: Programming: Languages: Python: Books</title>']

In [3]: response.xpath('//title/text()')
Out[3]: [<Selector xpath='//title/text()' data=u'Open Directory - Computers: Programming:'>]

In [4]: response.xpath('//title/text()').extract()
Out[4]: [u'Open Directory - Computers: Programming: Languages: Python: Books']

In [5]: response.xpath('//title/text()').re('(\w+):')
Out[5]: [u'Computers', u'Programming', u'Languages', u'Python']

3、编写新的Spider

import scrapy


class CsdnSpider(scrapy.Spider):
    name = "csdn"
    allowed_domains = ["csdn.net"]
    start_urls = [
        "https://blog.csdn.net/jiangwei0910410003/article/details/79436956",
        "https://blog.csdn.net/M7720EIoSi6oA9/article/details/81463841"
    ]

    def parse(self, response):
        for sel in response.xpath('//*[@id="asideProfile"]'):
            author = sel.xpath('div[1]/div[2]/p[1]/a/text()').extract()
            fans = sel.xpath('div[2]/dl[2]/dd/span/text()').extract()
            like = sel.xpath('div[2]/dl[3]/dd/span/text()').extract()
            comment = sel.xpath('div[2]/dl[4]/dd/span/text()').extract()
            print(author, fans, like, comment)

4、爬取

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

scrapy crawl csdn

五、使用了Item的Scrapy爬虫

1、定义Item

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

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

首先根据需要从csdn.net获取到的数据对item进行建模。 我们需要从csdn中获取作者名字、粉丝数量、喜欢数量、评论数量。 对此,在item中定义相应的字段。编辑 tutorial 目录中的 items.py 文件:

import scrapy


class CsdnItem(scrapy.Item):
    author = scrapy.Field()
    fans = scrapy.Field()
    like = scrapy.Field()
    comment = scrapy.Field()

2、编写新的Spider

import scrapy
from tutorial.items import CsdnItem


class CsdnSpider(scrapy.Spider):
    name = "csdn"
    allowed_domains = ["csdn.net"]
    start_urls = [
        "https://blog.csdn.net/jiangwei0910410003/article/details/79436956",
        "https://blog.csdn.net/M7720EIoSi6oA9/article/details/81463841"
    ]

    def parse(self, response):
        for sel in response.xpath('//*[@id="asideProfile"]'):
            item = CsdnItem()
            item['author'] = sel.xpath('div[1]/div[2]/p[1]/a/text()').extract()
            item['fans'] = sel.xpath('div[2]/dl[2]/dd/span/text()').extract()
            item['like'] = sel.xpath('div[2]/dl[3]/dd/span/text()').extract()
            item['comment'] = sel.xpath('div[2]/dl[4]/dd/span/text()').extract()
            yield item

3、爬取

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

scrapy crawl csdn

4、保存爬取到的数据到csdn_item.json

最简单存储爬取的数据的方式是使用 Feed exports(进入项目的根目录,执行下列命令启动Spider):

scrapy crawl csdn -o csdn_item.json

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

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

Gupao