• 基于Python使用scrapy-redis框架实现分布式爬虫 注


    注:本文是在http://www.111cn.net/sys/CentOS/63645.htmhttp://www.cnblogs.com/kylinlin/p/5198233.html的基础上加以改动的!版权归alex.shukylinlin所有。

    1.首先介绍一下:scrapy-redis框架  

        scrapy-redis:一个三方的基于redis的分布式爬虫框架,配合scrapy使用,让爬虫具有了分布式爬取的功能。github地址: https://github.com/darkrho/scrapy-redis ,

    mongodb 、mysql 或其他数据库:针对不同类型数据可以根据具体需求来选择不同的数据库存储。结构化数据可以使用mysql节省空间,非结构化、文本等数据可以采用mongodb等非关系型数据提高访问速度。具体选择可以自行百度谷歌,有很多关于sql和nosql的对比文章。

    2.介绍一下分布式原理:

        scrapy-redis实现分布式,其实从原理上来说很简单,这里为描述方便,我们把自己的核心服务器称为master,而把用于跑爬虫程序的机器称为slave。

    我们知 道,采用scrapy框架抓取网页,我们需要首先给定它一些start_urls,爬虫首先访问start_urls里面的url,再根据我们的具体逻辑,对里面的元素、或者是其他的二级、三级页面进行抓取。而要实现分布式,我们只需要在这个starts_urls里面做文章就行了。

    我们在master上搭建一个redis数据库(注意这个数据库只用作url的存储,不关心爬取的具体数据,不要和后面的mongodb或者mysql混淆),并对每一个需要爬取的网站类型,都开辟一个单独的列表字段。通过设置slave上scrapy-redis获取url的地址为master地址。这样的结果就是,尽管有多个slave,然而大家获取url的地方只有一个,那就是服务器master上的redis数据库。

    并且,由于scrapy-redis自身的队列机制,slave获取的链接不会相互冲突。这样各个slave在完成抓取任务之后,再把获取的结果汇总到服务器上(这时的数据存储不再在是redis,而是mongodb或者 mysql等存放具体内容的数据库了)

    这种方法的还有好处就是程序移植性强,只要处理好路径问题,把slave上的程序移植到另一台机器上运行,基本上就是复制粘贴的事情。

    3.分布式爬虫的实现:

        1.使用两台机器,一台是win10,一台是centos7(详情请看http://www.111cn.net/sys/CentOS/63645.htm),分别在两台机器上部署scrapy来进行分布式抓取一个网站

        2.centos7的ip地址为192.168.1.112,用来作为redis的master端,win10的机器作为slave

        3.master的爬虫运行时会把提取到的url封装成request放到redis中的数据库:“dmoz:requests”,并且从该数据库中提取request后下载网页,再把网页的内容存放到redis的另一个数据库中“dmoz:items”

        4.slave从master的redis中取出待抓取的request,下载完网页之后就把网页的内容发送回master的redis

        5.重复上面的3和4,直到master的redis中的“dmoz:requests”数据库为空,再把master的redis中的“dmoz:items”数据库写入到mongodb中

        6.master里的reids还有一个数据“dmoz:dupefilter”是用来存储抓取过的url的指纹(使用哈希函数将url运算后的结果),是防止重复抓取的

    4.scrapy-redis框架的安装:

        

    安装redis(http://blog.fens.me/linux-redis-install/

    windows安装redis

    下载地址:https://github.com/rgl/redis/downloads

    wps96F0.tmp

    选择最新版和你电脑的对应版本下载安装

    安装完成后,

    运行redis服务器的命令:安装目录下的redis-server.exe

    运行redis客户端的命令:安装目录下的redis-cli.exe

    centos7安装redis

    直接运行命令:yum install redis -y即可,安装完成后默认启动redis服务器

    安装完成后,redis默认是不能被远程连接的,此时要修改配置文件/etc/redis.conf

    #注释bind
    
    #bind 127.0.0.1

    修改后,重启redis服务器

    systemctl restart redis

    在centos7环境下启动redis服务器的命令:systemctl start redis,启动客户端的命令:redis-cli

    如果要增加redis的访问密码,修改配置文件/etc/redis.conf

    #取消注释requirepass
    
    requirepass redisredis  # redisredis就是密码(记得自己修改)

    增加了密码后,启动客户端的命令变为:redis-cli -a redisredis

    测试是否能远程登陆

    使用windows的命令窗口进入redis安装目录,用命令进行远程连接centos7的redis:

    redis-cli -h 192.168.1.112 -p 6379

    wps96F1.tmp

    在本机上测试是否能读取master的redis

    wps96F2.tmp

    在远程机器上读取是否有该数据

    wps96F3.tmp

    可以确信redis安装完成

    安装部署scrapy-redis

    安装scrapy-redis命令(https://github.com/rolando/scrapy-redis)

    pip install scrapy-redis

    部署scrapy-redis:

    slave端:在windows上的settings.py文件的最后增加如下一行

    REDIS_URL = 'redis://192.168.1.112:6379'

    master端:在centos7上的settings.py文件的最后增加如下两行

    REDIS_HOST = 'localhost'
    
    REDIS_PORT = 6379

    在windows中配置好了远程的redis地址后启动两个爬虫(启动爬虫没有顺序限制),此时在windows上查看redis,可以看到windows上运行的爬虫的确是从远程的reids里获取request的(因为本地的redis没有东西)

    图片3

     由此确认好了scrapy-redis安装配置完成

    使用redis-dump将redis的数据导出来查看(可选)

    在centos7上安装redis-dump (https://github.com/delano/redis-dump)

    yum -y install gcc ruby-devel rubygems compass gem

    修改rvm安装源(http://genepeng.com/index.php/346)

    复制代码
    复制代码
    gem sources --remove https://rubygems.org/
    
    gem sources -a https://ruby.taobao.org/
    
    gem sources -l
    
    gem install redis-dump -y
    复制代码
    复制代码

    运行了example里的dmoz之后,连接redis,查看到生成了以下的三个数据库,并且每个value对应的类型如下

    wps9705.tmp

    在centos7上使用redis-dump命令(redis-dump -u 127.0.0.1:6379 > db_full.json)导出该数据库,再查看存储到的数据(在这里我只提取了每个数据库的前几条)

    图片2

    下图就是上面数据库“dmoz:items”里所爬取的内容

    图片1

    将爬取到的数据导入到mongodb中

    等到爬虫结束后,此时运行process_items.py来把位于master的redis中的“dmoz:items”逐一读取到json中,所以如果要把item存储到mongodb中,就应该修改process_items.py文件,如下

    复制代码
    复制代码
    #!/usr/bin/env python
    
    # -*- coding: utf-8 -*-
    
    import json
    
    import redis
    
    import pymongo
    
    def main():
    
        # r = redis.Redis()
    
        r = redis.Redis(host='192.168.1.112',port=6379,db=0)
    
        client = pymongo.MongoClient(host='localhost', port=27017)
    
        db = client['dmoz']
    
        sheet = db['sheet']
    
        while True:
    
            # process queue as FIFO, change `blpop` to `brpop` to process as LIFO
    
            source, data = r.blpop(["dmoz:items"])
    
            item = json.loads(data)
    
            sheet.insert(item)
    
            try:
    
                print u"Processing: %(name)s <%(link)s>" % item
    
            except KeyError:
    
                print u"Error procesing: %r" % item
    
    if __name__ == '__main__':
    
        main()
    复制代码
    复制代码

    其实可以在爬虫一边运行的时候,一边运行process_items.py文件

    注意:如果要重新运行爬虫记得把master上的redis清空,因为master里的数据库“dmoz:dupefilter”是用来过滤重复的请求

    192.168.1.112:6379> flushdb
  • 相关阅读:
    EBS SQL > Form & Report
    oracle sql 优化分析点
    MRP 物料需求计划
    MRPII 制造资源计划
    Barcode128 应用实务
    Oracle SQL语句优化技术分析
    APPSQLAP10710 Online accounting could not be created. AP Invoice 无法创建会计分录
    Oracle数据完整性和锁机制
    ORACLE Responsibility Menu Reference to Other User
    EBS 常用 SQL
  • 原文地址:https://www.cnblogs.com/zhangxiaomeng1991/p/8318434.html
Copyright © 2020-2023  润新知