• 分布式爬虫


    分布式爬虫

    • 什么分布式

      分布式就是把一个系统拆分成若干个子系统, 每个子系统独立运行, 然后通过某种方式进行交互.

    • 什么是分布式爬虫

      狭义地讲, 需要将爬虫的多个组件拆分成子系统. 但是现在主流是只拆分出任务生产者, 建立一个生产消费者模型.由多台机器上的爬虫实例作为消费者去完成爬虫任务.

    scrapy的痛点

    • 爬虫实例中断后重启后, 内存保存的消息队列将会丢失, 实现爬虫重启功能比较复杂;
    • 去重中间件无法持久化, 中断后无法正常过滤;
    • 消息队列放在了内置类型QUEUE中, 无法简单地从外部查看;
    • 不共享消息队列, 可扩展性差;

    scrapy-redis

    https://github.com/rmax/scrapy-redis
    
    • 1
    • 安装

      pip install scrapy-redis
      
      • 1
    • SETTINGS设置

      • SCHEDULER

        更换调度器

        SCHEDULER = 'scrapy_redis.scheduler.Scheduler'
        
        • 1
      • SCHEDULER_QUEUE_CLASS

        更换消息队列

        SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'
        
        • 1
      • DUPEFILTER_CLASS

        更换过滤器, 将请求指纹保存在redis当中

        DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
        
        • 1
      • SCHEDULER_PERSIST

        消息队列持久化, 不会清空redis中的消息队列

        SCHEDULER_PERSIST = True
        
        • 1
      • REDIS配置

        # Redis settings
        REDIS_HOST = 'localhost'
        REDIS_PORT = 6379
        # Redis 参数配置
        REDIS_PARAMS = {"db": 5}
        
        • 1
        • 2
        • 3
        • 4
        • 5
    • SPIDER设置

      • 修改继承的父类为scrapy_redis.spiders.RedisSpider

        from scrapy_redis.spiders import RedisSpider
        
        class JdSearch(RedisSpider):
        
        • 1
        • 2
        • 3
      • 添加redis_key配置

        redis_key = f"{name}:start_urls"
        
        • 1
    • 将生产者从scrapy项目中拆分出去

      import redis
      import time
      import json
      
      redis_con = redis.Redis(host='localhost', port=6379, db=5)
      
      
      def search_producer():
          for keyword in ["鼠标", "键盘", "显卡", "耳机"]:
              for page_num in range(1, 11):
                  url = f"https://search.jd.com/Search?keyword={keyword}&page={page_num}"
                  meta = {
                      "sta_date": time.strftime("%Y-%m-%d"),
                      "keyword": keyword,
                      "page_num": page_num
                  }
      
                  task = json.dumps({
                      "url": url,
                      "body": '',
                      "method": "GET",
                      "meta": meta
                  })
                  redis_con.lpush("jd_search:start_urls", task)
      
      
      if __name__ == "__main__":
          search_producer()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
    • 重写start_requests

          def make_request_from_data(self, data):
              task = json.loads(data.decode("utf-8"))
              return scrapy.http.FormRequest(url=task['url'],
                                             formdata=json.loads(task['body']) if task['body'] else '',
                                             method=task['method'],
                                             meta=task['meta'],
                                             dont_filter=False,
                                             callback=self.parse_search,
                                             errback=self.process_error)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
  • 相关阅读:
    解决MySQL大版本升级导致.Net(C#)程序连接报错问题
    第52天:Web应用、手写Web框架、Django的下载安装
    C++【多态】
    什么是贪财型人格,如何改变贪财型性格
    NF-ResNet:去掉BN归一化,值得细读的网络信号分析 | ICLR 2021
    Flink学习之旅:(二)构建Flink demo工程并提交到集群执行
    SiR-PEG4-alkyne 硅-罗丹明-四聚乙二醇-炔基 | SIR小分子荧光染料
    SpringBoot整合SpringSecrity+JWT ---复制即用
    神经网络训练准确率不变,神经网络越训练越差
    国内多位架构大牛强烈推荐的大型分布式手册
  • 原文地址:https://blog.csdn.net/m0_57713054/article/details/128045446