zoukankan      html  css  js  c++  java
  • 基于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
  • 相关阅读:
    一步步介绍网页之--> intro.js的使用
    使用 intro.js 使项目介绍更加完美
    完整版中国省市县数据 存储到数据库中
    java 使用openoffice 转换文档,成.pdf,实现在线预览效果
    jsp 页面传多个id 到java后台的处理方式
    CCF推荐国际刊物会议列表2015
    百度ABCOP团队校招提前Offer等你来挑战
    高性能计算中心汇总
    Linux SSH 远程登录后显示-bash-4.1$的解决办法
    Coolpad Y1刷机方法
  • 原文地址:https://www.cnblogs.com/zhangxiaomeng1991/p/8318434.html
Copyright © 2011-2022 走看看