zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    JDK、J2EE、J2SE、J2ME的区别
    消息队列
    Unity3D 导入aar注意事项
    汇编小结
    构造函数语意学--笔记
    androidStudio 改包名
    新手用车
    北京临牌办理与续办
    h5+
    apache.http.MalformedChunkCodingException: Chunked stream ended unexpectedly
  • 原文地址:https://www.cnblogs.com/kai-/p/12686801.html
Copyright © 2011-2022 走看看