Scrapy 入门教程

发布日期:2019-07-23 19:56:10 阅读数: 354次 来源: 作者:

Scrapy 是用 Python 实现的一个为了爬取网站数据、提取布局性数据而编写的使用框架。

Scrapy 常使用在包罗数据挖掘,消息处置或存储汗青数据等一系列的法式中。

凡是我们能够很简单的通过 Scrapy 框架实现一个爬虫,抓取指定网站的内容或图片。


Scrapy架构图(绿线是数据流向)

  • Scrapy Engine(引擎): 担任Spider、ItemPipeline、Downloader、Scheduler两头的通信,信号、数据传送等。

  • Scheduler(安排器): 它担任接管引擎发送过来的Request请求,并按照必然的体例进行拾掇摆列,入队,当引擎需要时,交还给引擎。

  • Downloader(下载器):担任下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处置,

  • Spider(爬虫):它担任处置所有Responses,从平分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(安排器).

  • Item Pipeline(管道):它担任处置Spider中获取到的Item,并进行进行后期处置(细致阐发、过滤、存储等)的处所。

  • Downloader Middlewares(下载两头件):你能够看成是一个能够自定义扩展下载功能的组件。

  • Spider Middlewares(Spider两头件):你能够理解为是一个能够自定扩展和操作引擎和Spider两头通信的功能组件(好比进入Spider的Responses;和从Spider出去的Requests)

Scrapy的运作流程

代码写好,法式起头运转...

  • 1 引擎:Hi!Spider, 你要处置哪一个网站?
  • 2 Spider:老迈要我处置xxxx.com。
  • 3 引擎:你把第一个需要处置的URL给我吧。
  • 4 Spider:给你,第一个URL是xxxxxxx.com。
  • 5 引擎:Hi!安排器,我这有request请求你帮我排序入队一下。
  • 6 安排器:好的,正在处置你等一下。
  • 7 引擎:Hi!安排器,把你处置好的request请求给我。
  • 8 安排器:给你,这是我处置好的request
  • 9 引擎:Hi!下载器,你按照老迈的下载两头件的设置帮我下载一下这个request请求
  • 10 下载器:好的!给你,这是下载好的工具。(若是失败:sorry,这个request下载失败了。然后引擎告诉安排器,这个request下载失败了,你记实一下,我们待会儿再下载)
  • 11 引擎:Hi!Spider,这是下载好的工具,而且曾经按照老迈的下载两头件处置过了,你本身处置一下(留意!这儿responses默认是交给def parse()这个函数处置的)
  • 12 Spider:(处置完毕数据之后对于需要跟进的URL),Hi!引擎,我这里有两个成果,这个是我需要跟进的URL,还有这个是我获取到的Item数据。
  • 13 引擎:Hi !管道 我这儿有个item你帮我处置一下!安排器!这是需要跟进URL你帮我处置下。然后从第四步起头轮回,直到获取完老迈需要全数消息。
  • 14 管道安排器:好的,此刻就做!

留意!只要当安排器中不具有任何request了,整个法式才会遏制,(也就是说,对于下载失败的URL,Scrapy也会从头下载。)


制造 Scrapy 爬虫 一共需要4步:

  1. 新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
  2. 明白方针 (编写items.py):明白你想要抓取的方针
  3. 制造爬虫 (spiders/xxspider.py):制造爬虫起头爬取网页
  4. 存储内容 (pipelines.py):设想管道存储爬取内容

安装

Windows 安装体例

升级 pip 版本:

pip install --upgrade pip

通过 pip 安装 Scrapy 框架:

pip install Scrapy

Ubuntu 安装体例

安装非 Python 的依赖:

sudo apt-get install python-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev

通过 pip 安装 Scrapy 框架:

sudo pip install scrapy

Mac OS 安装体例

对于Mac OS系统来说,因为系统本身会援用自带的python2.x的库,因而默认安装的包是不克不及被删除的,可是你用python2.x来安装Scrapy会报错,用python3.x来安装也是报错,我最终没有找到间接安装Scrapy的方式,所以我用另一种安装体例来说一下安装步调,处理的体例是就是利用virtualenv来安装。

$ sudo pip install virtualenv
$ virtualenv scrapyenv
$ cd scrapyenv
$ source bin/activate
$ pip install Scrapy

安装后,只需在号令终端输入 scrapy,提醒雷同以下成果,代表曾经安装成功。


入门案例

进修方针

  • 建立一个Scrapy项目
  • 定义提取的布局化数据(Item)
  • 编写爬取网站的 Spider 并提取出布局化数据(Item)
  • 编写 Item Pipelines 来存储提取到的Item(即布局化数据)

一. 新建项目(scrapy startproject)

在起头爬取之前,必需建立一个新的Scrapy项目。进入自定义的项目目次中,运转下列号令:

scrapy startproject mySpider

此中, mySpider 为项目名称,能够看到将会建立一个 mySpider 文件夹,目次布局大致如下:

下面来简单引见一下各个次要文件的感化:

mySpider/
    scrapy.cfg
    mySpider/
        __init__.py
        items.py
        pipelines.py
        settings.py
        spiders/
            __init__.py
            ...

这些文件别离是:

  • scrapy.cfg: 项目标设置装备摆设文件。
  • mySpider/: 项目标Python模块,将会从这里援用代码。
  • mySpider/items.py: 项目标方针文件。
  • mySpider/pipelines.py: 项目标管道文件。
  • mySpider/settings.py: 项目标设置文件。
  • mySpider/spiders/: 存储爬虫代码目次。

二、明白方针(mySpider/items.py)

我们筹算抓取 http://www.itcast.cn/channel/teacher.shtml 网站里的所有讲师的姓名、职称和小我消息。

  1. 打开 mySpider 目次下的 items.py。

  2. Item 定义布局化数据字段,用来保留爬取到的数据,有点像 Python 中的 dict,可是供给了一些额外的庇护削减错误。

  3. 能够通过建立一个 scrapy.Item 类, 而且定义类型为 scrapy.Field 的类属性来定义一个 Item(能够理解成雷同于 ORM 的映照关系)。

  4. 接下来,建立一个 ItcastItem 类,和建立 item 模子(model)。

    import scrapy
    
    class ItcastItem(scrapy.Item):
       name = scrapy.Field()
       title = scrapy.Field()
       info = scrapy.Field()
    

三、制造爬虫 (spiders/itcastSpider.py)

爬虫功能要分两步:

1. 爬数据

在当前目次下输入号令,将在mySpider/spider目次下建立一个名为itcast的爬虫,并指定爬取域的范畴:

scrapy genspider itcast "itcast.cn"

打开 mySpider/spider目次里的 itcast.py,默认添加了下列代码:

import scrapy

class ItcastSpider(scrapy.Spider):
    name = "itcast"
    allowed_domains = ["itcast.cn"]
    start_urls = (
        'http://www.itcast.cn/',
    )

    def parse(self, response):
        pass

其实也能够由我们自行建立itcast.py并编写上面的代码,只不外利用号令能够免除编写固定代码的麻烦

要成立一个Spider, 你必需用scrapy.Spider类建立一个子类,并确定了三个强制的属性 和 一个方式。

name = "" :这个爬虫的识别号称,必需是独一的,在分歧的爬虫必需定义分歧的名字。

allow_domains = [] 是搜刮的域名范畴,也就是爬虫的束缚区域,划定爬虫只爬取这个域名下的网页,不具有的URL会被忽略。

start_urls = () :爬取的URL元祖/列表。爬虫从这里起头抓取数据,所以,第一次下载的数据将会从这些urls起头。其他子URL将会从这些起始URL中承继性生成。

parse(self, response) :解析的方式,每个初始URL完成下载后将被挪用,挪用的时候传入从每一个URL传回的Response对象来作为独一参数,次要感化如下:

担任解析前往的网页数据(response.body),提取布局化数据(生成item)
生成需要下一页的URL请求。
将start_urls的值点窜为需要爬取的第一个url

start_urls = ("http://www.itcast.cn/channel/teacher.shtml",)

点窜parse()方式

def parse(self, response):
    filename = "teacher.html"
    open(filename, 'w').write(response.body)

然后运转一下看看,在mySpider目次下施行:

scrapy crawl itcast

是的,就是 itcast,看上面代码,它是 ItcastSpider 类的 name 属性,也就是利用 scrapy genspider号令的独一爬虫名。

运转之后,若是打印的日记呈现 [scrapy] INFO: Spider closed (finished),代表施行完成。 之后当前文件夹中就呈现了一个 teacher.html 文件,里面就是我们方才要爬取的网页的全数源代码消息。

留意: Python2.x默认编码情况是ASCII,当和取回的数据编码格局纷歧致时,可能会形成乱码;我们能够指定保留内容的编码格局,一般环境下,我们能够在代码最上方添加

import sys
reload(sys)
sys.setdefaultencoding("utf-8")

这三行代码是 Python2.x 里处理中文编码的全能钥匙,颠末这么多年的吐槽后 Python3 学乖了,默认编码是Unicode了...(祝大师早日拥抱Python3)

2. 取数据

爬取整个网页完毕,接下来的就是的取过程了,起首不雅察页面源码:

<div class="li_txt">
    <h3>  xxx  </h3>
    <h4> xxxxx </h4>
    <p> xxxxxxxx </p>

是不是一目了然?间接上 XPath 起头提取数据吧。

xpath 方式,我们只需要输入的 xpath 法则就能够定位到响应 html 标签节点,细致内容能够查看 xpath 教程。

不会 xpath 语法不妨,Chrome 给我们供给了一键获取 xpath 地址的方式(右键->查抄->copy->copy xpath),如下图:

这里给出一些 XPath 表达式的例子和对应的寄义:

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

举例我们读取网站 http://www.itcast.cn/ 的网站题目,点窜 itcast.py 文件代码如下::

# -*- coding: utf-8 -*-
import scrapy

# 以下三行是在 Python2.x版本中处理乱码问题,Python3.x 版本的能够去掉
import sys
reload(sys)
sys.setdefaultencoding("utf-8")

class Opp2Spider(scrapy.Spider):
    name = 'itcast'
    allowed_domains = ['itcast.com']
    start_urls = ['http://www.itcast.cn/']

    def parse(self, response):
        # 获取网站题目
        context = response.xpath('/html/head/title/text()')   
       
        # 提取网站题目
        title = context.extract_first()  
        print(title) 
        pass

施行以下号令:

$ scrapy crawl itcast
...
...
传智播客长网-好口碑IT培训机构,一样的教育,纷歧样的质量
...
...

我们之前在 mySpider/items.py 里定义了一个 ItcastItem 类。 这里引入进来:

from mySpider.items import ItcastItem

然后将我们获得的数据封装到一个 ItcastItem 对象中,能够保留每个教员的属性:

from mySpider.items import ItcastItem

def parse(self, response):
    #open("teacher.html","wb").write(response.body).close()

    # 存放教员消息的调集
    items = []

    for each in response.xpath("//div[@class='li_txt']"):
        # 将我们获得的数据封装到一个 `ItcastItem` 对象
        item = ItcastItem()
        #extract()方式前往的都是unicode字符串
        name = each.xpath("h3/text()").extract()
        title = each.xpath("h4/text()").extract()
        info = each.xpath("p/text()").extract()

        #xpath前往的是包含一个元素的列表
        item['name'] = name[0]
        item['title'] = title[0]
        item['info'] = info[0]

        items.append(item)

    # 间接前往最初数据
    return items

我们临时先不处置管道,后面会细致引见。

保留数据

scrapy保留消息的最简单的方式次要有四种,-o 输出指定格局的文件,号令如下:

scrapy crawl itcast -o teachers.json

json lines格局,默认为Unicode编码

scrapy crawl itcast -o teachers.jsonl

csv 逗号表达式,可用Excel打开

scrapy crawl itcast -o teachers.csv

xml格局

scrapy crawl itcast -o teachers.xml

思虑

若是将代码改成下面形式,成果完全一样。

请思虑 yield 在这里的感化(Python yield 利用浅析):

# -*- coding: utf-8 -*-
import scrapy
from mySpider.items import ItcastItem

# 以下三行是在 Python2.x版本中处理乱码问题,Python3.x 版本的能够去掉
import sys
reload(sys)
sys.setdefaultencoding("utf-8")

class Opp2Spider(scrapy.Spider):
    name = 'itcast'
    allowed_domains = ['itcast.com']
    start_urls = ("http://www.itcast.cn/channel/teacher.shtml",)

    def parse(self, response):
        #open("teacher.html","wb").write(response.body).close()

        # 存放教员消息的调集
        items = []

        for each in response.xpath("//div[@class='li_txt']"):
            # 将我们获得的数据封装到一个 `ItcastItem` 对象
            item = ItcastItem()
            #extract()方式前往的都是unicode字符串
            name = each.xpath("h3/text()").extract()
            title = each.xpath("h4/text()").extract()
            info = each.xpath("p/text()").extract()

            #xpath前往的是包含一个元素的列表
            item['name'] = name[0]
            item['title'] = title[0]
            item['info'] = info[0]

           亚博 items.append(item)

        # 间接前往最初数据
        return items
本文由亚博手机app编辑整理亚博手机app