• scrapy 分布式爬虫


    介绍

    原来 scrapy 的 Scheduler 维护的是本机的任务队列(存放 Request 对象及其回调函数等信息)+ 本机的去重队列(存放访问过的url地址)

    所以实现分布式爬取的关键就是,找一台专门的主机上运行一个共享的队列比如 Redis,
    然后重写 Scrapy 的 Scheduler,让新的 Scheduler 到共享队列存取 Request,并且去除重复的 Request 请求,所以总结下来,实现分布式的关键就是三点:

    #1、共享队列
    #2、重写Scheduler,让其无论是去重还是任务都去访问共享队列
    #3、为Scheduler定制去重规则(利用redis的集合类型)
    

    安装

    pip install scrapy-redis
    
    #源码:
    D:python3.6Libsite-packagesscrapy_redis
    

    scrapy-redis 组件

    只使用scrapy-redis的去重功能

    在 settings.py 中配置链接 Redis

    REDIS_HOST = 'localhost'                            # 主机名
    REDIS_PORT = 6379                                   # 端口
    REDIS_URL = 'redis://user:pass@hostname:9001'       # 连接URL(优先于以上配置)
    REDIS_PARAMS  = {'password':'redis123'}             # Redis连接参数
    REDIS_PARAMS['redis_cls'] = 'myproject.RedisClient' # 指定连接Redis的Python模块
    REDIS_ENCODING = "utf-8"                            # redis编码类型 
    

    让 scrapy 使用共享的去重队列

    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    
    from scrapy.dupefilters import RFPDupeFilter
    from scrapy.core.scheduler import Scheduler
    

    将request请求转成一串字符后再存入集合

    from scrapy.http import Request
    from scrapy.utils.request import request_fingerprint
    
    req = Request(url='http://www.baidu.com')
    result=request_fingerprint(req)
    print(result) #75d6587d87b3f4f3aa574b33dbd69ceeb9eafe7b
    

    注意:
    UR L参数位置不同时,计算结果一致;
    默认请求头不在计算范围,include_headers 可以设置指定请求头

    req = Request(url='http://www.baidu.com?name=8&id=1',callback=lambda x:print(x),cookies={'k1':'vvvvv'})
    result1 = request.request_fingerprint(req,include_headers=['cookies',])
    print(result)
     
    req = Request(url='http://www.baidu.com?id=1&name=8',callback=lambda x:print(x),cookies={'k1':666})
    result2 = request.request_fingerprint(req,include_headers=['cookies',])
    print(result1 == result2) #True
    

    使用 scrapy-redis 的去重 + 调度实现分布式爬取

    settings.py 配置

    # Enables scheduling storing requests queue in redis.
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"   
    
    # 调度器将不重复的任务用 pickle 序列化后放入共享任务队列,默认使用优先级队列(默认),其他:PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表)               
    
    

    步骤

    1 原来的爬虫继承

    from scrapy_redis.spiders import RedisSpider
    
    class ChoutiSpider(RedisSpider):
        name = 'chouti'  # 爬虫名字
        redis_key = 'myspider:start_urls'
    

    2 在 settings 中配置

      SCHEDULER = "scrapy_redis.scheduler.Scheduler"
      DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
      ITEM_PIPELINES = {
         'scrapy_redis.pipelines.RedisPipeline': 300
      }
    

    3 多台机器上启动 scrapy

    4 向 redis 中发送起始 url

    lpush myspider:start_urls https://www.cnblogs.com
    
  • 相关阅读:
    db4o 7.4 for .net3.5试用手记
    ruby学习笔记(2)类的基本使用
    温故而知新:设计模式之适配器模式(Adapter)
    Silverlight:Dependency Property(依赖属性)学习笔记
    Silverlight中的帧
    关闭与恢复visual studio实时调试器
    温故而知新:设计模式之桥接模式(Bridge)
    温故而知新:设计模式之单件模式(Singleton)
    一段oracle中的“复杂”分组统计sql
    VisualTreeHelper
  • 原文地址:https://www.cnblogs.com/kai-/p/12686801.html
Copyright © 2020-2023  润新知