zoukankan      html  css  js  c++  java
  • 爬虫开发14.scrapy框架之分布式操作

    分布式爬虫

    一.redis简单回顾

      1.启动redis:

        mac/linux:   redis-server redis.conf

        windows: redis-server.exe redis-windows.conf

      2.对redis配置文件进行配置:

        - 注释该行:bind 127.0.0.1,表示可以让其他ip访问redis

        - 将yes该为no:protected-mode no,表示可以让其他ip操作redis

    二.scrapy基于redis的数据持久化操作流程

      1.安装scrapy-redis组件:

        - pip install scrapy-redis

        - scrapy-redis是基于scrapy框架开发出的一套组件,其作用就是可以让scrapy实现分布式爬虫。

      2.编写爬虫文件:

        - 同之前scrapy中基于Spider或者CrawlSpider的编写方式一致。

      3.编写管道文件:

        - 在scrapy-redis组件中已经帮助我们封装好了一个专门用于连接存储redis数据库的管道(RedisPipeline),因此我们直接使用即可,无需自己编写管道文件。

      4.编写配置文件:

        - 在settings.py中开启管道,且指定使用scrapy-redis中封装好的管道。

    ITEM_PIPELINES = {
        'scrapy_redis.pipelines.RedisPipeline': 400
    }

    - 该管道默认会连接且将数据存储到本机的redis服务中,如果想要连接存储到其他redis服务中需要在settings.py中进行如下配置:

    REDIS_HOST = 'redis服务的ip地址'
    REDIS_PORT = 6379
    REDIS_ENCODING = ‘utf-8’
    REDIS_PARAMS = {‘password’:’123456’}

    三.redis分布式部署

      1.scrapy框架是否可以自己实现分布式?

        - 不可以。原因有二。

          其一:因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls列表中的url。(多台机器无法共享同一个调度器)

          其二:多台机器爬取到的数据无法通过同一个管道对数据进行统一的数据持久出存储。(多台机器无法共享同一个管道)

      2.redis实现分布式基本流程:

        - 使用基于scrapy-redis组件中的爬虫文件。

    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    from movieproject.items import MovieprojectItem
    #导入scrapy-redis中的模块
    from scrapy_redis.spiders import RedisCrawlSpider
    
    class NnSpider(RedisCrawlSpider):
        name = 'nn' 
        allowed_domains = ['www.id97.com']
        #redis_key表示调度器中的队列(将要爬取的页面数据对应的url都需要放置到调度器队列中)
        redis_key = 'nnspider:start_urls'
    
        # 根据规则提取所有的页码链接
        page_link = LinkExtractor(allow=r'/movie/?page=d')
        detail_link = LinkExtractor(restrict_xpaths='//div[contains(@class,"col-xs-1-5")]/div/a')
        # detail_link = LinkExtractor(allow=r'/movie/d+.html$')
        # follow : 是否跟进
        rules = (
            # 所有的页码不用处理,跟进即可
            Rule(page_link, follow=True),
            # 所有的详情页处理,不用跟进
            Rule(detail_link, callback='parse_item', follow=False),
        )
    
        def parse_item(self, response):
            # 创建一个item对象
            item = MovieprojectItem()
            # 电影海报
            item['post'] = response.xpath('//a[@class="movie-post"]/img/@src').extract_first()
            # 电影名字
            item['name'] = response.xpath('//h1').xpath('string(.)').extract_first()
         
            yield item

    - 使用scrapy-redis组件中封装好的调度器,将所有的url存储到该指定的调度器中,从而实现了多台机器的调度器共享。

    # 使用scrapy-redis组件的去重队列
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    # 使用scrapy-redis组件自己的调度器
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    # 是否允许暂停
    SCHEDULER_PERSIST = True

     - 使用scrapy-redis组件中封装好的管道,将每台机器爬取到的数据存储通过该管道存储到redis数据库中,从而实现了多台机器的管道共享。

    ITEM_PIPELINES = {
    
       'scrapy_redis.pipelines.RedisPipeline': 400,
    }
  • 相关阅读:
    VC 多文档用户界面设计
    如何把Windows7 库 更改成 我的电脑
    解决多文档程序框架中建立新的子框架类后出现“创建空文档失败”的问题
    我们从UNIX之父Dennis Ritchie​身上学到了什么
    在Unicode环境下读出和写入文件
    Android活动的生命周期
    Godaddy 上的域名服务器状态查询
    v8 javascript SHELL
    vim E492: Not an editor command: ^M
    Ubuntu 11.10不能使用USB安装的解决方法
  • 原文地址:https://www.cnblogs.com/sunny666/p/10542674.html
Copyright © 2011-2022 走看看