zoukankan      html  css  js  c++  java
  • 分布式爬虫(scrapy-redis)

     - 为什么原生的scrapy不能实现分布式

       - 调度器不能被共享

       - 管道无法被共享

     - scrapy-redis组件的作用是什么

       - 提供了可以被共享的调度器和管道
     - 分布式爬虫实现流程

    1.环境安装:pip install scrapy-redis
    2.创建工程
    3.创建爬虫文件:RedisCrawlSpider  RedisSpider
        - scrapy genspider -t crawl xxx www.xxx.com
    4.对爬虫文件中的相关属性进行修改:
        - 导报:from scrapy_redis.spiders import RedisCrawlSpider
        - 将当前爬虫文件的父类设置成RedisCrawlSpider
        - 将起始url列表替换成redis_key = 'xxx'(调度器队列的名称)
    5.在配置文件中进行配置:
        - 使用组件中封装好的可以被共享的管道类:
            ITEM_PIPELINES = {
                'scrapy_redis.pipelines.RedisPipeline': 400
                }
        - 配置调度器(使用组件中封装好的可以被共享的调度器)
            # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
            DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
            # 使用scrapy-redis组件自己的调度器
            SCHEDULER = "scrapy_redis.scheduler.Scheduler"
            # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
            SCHEDULER_PERSIST = True
    
         - 指定存储数据的redis:
            REDIS_HOST = 'redis服务的ip地址'
            REDIS_PORT = 6379
    
         - 配置redis数据库的配置文件
            - 取消保护模式:protected-mode no
            - bind绑定: #bind 127.0.0.1
    
         - 启动redis
    
    6.执行分布式程序
        scrapy runspider xxx.py
    
    7.向调度器队列中仍入一个起始url:
        在redis-cli中执行:
    

     - 爬取抽屉网 标题和作者

    # -*- coding: utf-8 -*-
    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    from scrapy_redis.spiders import RedisCrawlSpider
    from redischoutipro.items import RedischoutiproItem
    class ChoutiSpider(RedisCrawlSpider):
        name = 'chouti'
    
        redis_key = "chouti" # 调度器队列名字
    
        rules = (
            Rule(LinkExtractor(allow=r'/all/hot/recent/d+'), callback='parse_item', follow=True),
        )
    
        def parse_item(self, response):
            div_list = response.xpath('//div[@class="item"]')
            for div in div_list:
                title = div.xpath('./div[4]/div[1]/a/text()').extract_first()
                author = div.xpath('./div[4]/div[2]/a[4]/b/text()').extract_first()
                item = RedischoutiproItem()
                item["title"] = title
                item["author"] = author
    
                yield item
    spiders.chouti.py
    import scrapy
    
    
    class RedischoutiproItem(scrapy.Item):
        # define the fields for your item here like:
        title = scrapy.Field()
        author = scrapy.Field()
    items
    ITEM_PIPELINES = {
        'scrapy_redis.pipelines.RedisPipeline': 400
    }
    
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    SCHEDULER_PERSIST = True  #数据指纹
    
    REDIS_HOST = '127.0.0.1'
    
    REDIS_PORT = 6379
    settings

      - 执行命令:进入项目中的spiders

    scrapy runspider chouti.py

       - 打开redis向队列扔一个url

     lpush chouti https://dig.chouti.com/all/hot/recent/1

       - keys * 之后你会看到自动生成了:

         - requests :数据指纹(密文)

         - items: 数据都在这

         - dupefilter: 用来存储抓取过的 url 的 fingerprint(使用哈希函数将url运算后的结果),防止重复抓取,只要 redis 不清空,就可以进行断点续爬

    # 查看数据
    lrange chouti:items 0 -1
  • 相关阅读:
    021.day21 反射 Class类 反射常用操作
    020.day20 线程概述 多线程优缺点 线程的创建 线程常用方法 生命周期 多线程同步
    019.day19 缓冲流 对象流 标准输入输出流
    018.day18 map集合如何实现排序 File类 IO流 字节流 字符流 编码
    017.day17 Map接口 克隆 treeSet集合排重缺陷
    016.day16 HashSet TreeSet 比较器Comparable Comparator
    015.day15
    014.day14
    013.day13
    线程
  • 原文地址:https://www.cnblogs.com/lzmdbk/p/10477982.html
Copyright © 2011-2022 走看看