zoukankan      html  css  js  c++  java
  • 路飞学城—Python爬虫实战密训班 第三章

     

    路飞学城—Python爬虫实战密训班 第三章

    一、scrapy-redis插件实现简单分布式爬虫

    scrapy-redis插件用于将scrapy和redis结合实现简单分布式爬虫:
        - 定义调度器
        - 定义去重规则: 本质利用redis 集合元素不重复(被调度器使用) # 看源码request_seen函数
     
    安装: pip3 install scrapy-redis
    

      

    1. redis配置文件settings.py

    #from scrapy_redis import defaults                         # 查看默认配置
    REDIS_HOST = '192.168.11.81'                            # 主机名
    REDIS_PORT = 6379                                       # 端口
    # REDIS_URL = 'redis://user:pass@hostname:9001'           # 连接URL(优先于以上配置)
    # REDIS_PARAMS  = {}                                      # Redis连接参数             默认:REDIS_PARAMS = {'socket_timeout': 30,'socket_connect_timeout': 30,'retry_on_timeout': True,'encoding': REDIS_ENCODING,})
    # REDIS_PARAMS['redis_cls'] = 'myproject.RedisClient'     # 指定连接Redis的Python模块  默认:redis.StrictRedis
    REDIS_ENCODING = "utf-8"                                # redis编码类型             默认:'utf-8'
    连接Redis
    from scrapy_redis.scheduler import Scheduler
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"        # 使用该调度器,scrapy-redis原生调度器被替换掉
    
    from scrapy_redis.queue import PriorityQueue
    from scrapy_redis import picklecompat
    SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'              # 默认使用优先级队列(默认),其他:PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表)
    SCHEDULER_QUEUE_KEY = '%(spider)s:requests'                              # 调度器中请求存放在redis中的key
    SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat"                      # 对保存到redis中的数据进行序列化,默认使用pickle
    SCHEDULER_PERSIST = True                                                  # 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
    SCHEDULER_FLUSH_ON_START = False                                          # 是否在开始之前清空 调度器和去重记录,True=清空,False=不清空。本地测试可以为true,实际工作中False
    SCHEDULER_IDLE_BEFORE_CLOSE = 10                                          # 去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
    SCHEDULER_DUPEFILTER_KEY = '%(spider)s:dupefilter'                      # 去重规则,在redis中保存时对应的key
    SCHEDULER_DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'      # 去重规则对应处理的类
    设置调度器
    from scrapy_redis.pipelines import RedisPipeline
    
    ITEM_PIPELINES = {
       'scrapy_redis.pipelines.RedisPipeline': 300,
    }
    
    REDIS_ITEMS_KEY = '%(spider)s:items'
    REDIS_ITEMS_SERIALIZER = 'json.dumps'    # 指定下序列化
    数据持久化

    2. 当url太长时,数据库保存占空间,创建唯一标识符

    from scrapy.utils import request
    from scrapy.http import Request
    
    
    obj1 = Request(url='http://www.baidu.com?id=1&name=3')
    obj2 = Request(url='http://www.baidu.com?name=3&id=1')        # 当传参一致时,创建的标识符也一样
    
    v = request.request_fingerprint(obj1)
    print(v)
    v = request.request_fingerprint(obj2)
    print(v)
    test.py

    3. 起始URL相关

    from scrapy_redis.pipelines import RedisSpider
    class ChoutiSpider(scrapy.RedisSpider):
        name = "chouti"
        allowed_domains = ["chouti.com"]
    
        def parse(self, response):
            for i in range(0,10):
                yield
    chouti.py:不用写起始url,但是这个爬虫不会终止, 不用redis的话 爬虫下载完url后会终止。

    4. 小结

    1. memcached
         
    2. Django缓存
     
    3. redis
        - 连接
            - StrictRedis()
            - Redis(StrictRedis)    # 继承StrictRedis
            - 连接池
             
        - 基本操作
            ..
             
        - 事务
     
        - 发布和订阅
         
    4. scrapy-redis流程
        4.1 引擎,获取起始Request对象, 添加(pickle)到调度器
            - scrapy内部调度器
            - scrapy-redis调度器三个选择:先进先出列表,后进先出列表,有序集合
     
        4.2 调度器通知下载器可以开始下载,去调度器中获取request对象(通过pickle存储request对象),下载器进行下载           
         
        4.3 爬虫parse方法,yield返回对象item或request
            - item              交给pipeline处理
            - request           交给调度去处理,调用DUPEFILTER_CLASS去检查是否已经访问过,来决定request重新放置调度器或者丢弃
     
     
         
     
        scrapy-redis扩种:
            - 中间件
            - 基于信号的扩展
    

    三、scrapy-redis示例

    # DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    #
    #
    # from scrapy_redis.scheduler import Scheduler
    # from scrapy_redis.queue import PriorityQueue
    # SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    # SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'          # 默认使用优先级队列(默认),其他:PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表)
    # SCHEDULER_QUEUE_KEY = '%(spider)s:requests'                         # 调度器中请求存放在redis中的key
    # SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat"                  # 对保存到redis中的数据进行序列化,默认使用pickle
    # SCHEDULER_PERSIST = True                                            # 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
    # SCHEDULER_FLUSH_ON_START = False                                    # 是否在开始之前清空 调度器和去重记录,True=清空,False=不清空
    # SCHEDULER_IDLE_BEFORE_CLOSE = 10                                    # 去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
    # SCHEDULER_DUPEFILTER_KEY = '%(spider)s:dupefilter'                  # 去重规则,在redis中保存时对应的key
    # SCHEDULER_DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'# 去重规则对应处理的类
    #
    #
    #
    # REDIS_HOST = '10.211.55.13'                           # 主机名
    # REDIS_PORT = 6379                                     # 端口
    # # REDIS_URL = 'redis://user:pass@hostname:9001'       # 连接URL(优先于以上配置)
    # # REDIS_PARAMS  = {}                                  # Redis连接参数             默认:REDIS_PARAMS = {'socket_timeout': 30,'socket_connect_timeout': 30,'retry_on_timeout': True,'encoding': REDIS_ENCODING,})
    # # REDIS_PARAMS['redis_cls'] = 'myproject.RedisClient' # 指定连接Redis的Python模块  默认:redis.StrictRedis
    # REDIS_ENCODING = "utf-8"                              # redis编码类型             默认:'utf-8'
    配置文件
    import scrapy
    
    
    class ChoutiSpider(scrapy.Spider):
        name = "chouti"
        allowed_domains = ["chouti.com"]
        start_urls = (
            'http://www.chouti.com/',
        )
    
        def parse(self, response):
            for i in range(0,10):
                yield
    爬虫文件

    四、总结

      WuSir为了给我们介绍分布式爬虫,他首先用了个典型的例子举例。问题是:在不考虑开进程和线程(比如这些都已经做好了)如何提高爬虫的性能?说到这可能大家心里都已经有答案了,没错,我最帅!

     
      好了,回到正题;既然进程和线程都不需要我们考虑的情况下,那么我们的一般选择就应该是多加些机器一起爬,但是随之而来的又有一个问题、单纯的增加机器,不让它们相互协调的工作,这会造成会重复的做相同的无用功,也就是会爬到相同的URL。要是不让它们协调在一起,这个方案也就没意义了。
     
      既然问题已经抛出,那么我们就可以引入答案了,也就是如题所说的:scrapy-redis、使用该模块可以帮助我们实现分布式爬虫。我们需要做的则是对他进行相应的操作和配置或者扩展,来进行使用它即可达到我们的目的。

      

  • 相关阅读:
    day 66 crm(3) 自创组件stark界面展示数据
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件
    用 Python+nginx+django 打造在线家庭影院
    django -admin 源码解析
    day 64 crm项目(1) admin组件的初识别以及应用
    云链接 接口不允许 情况 解决方法 mysql Host is not allowed to connect to this MySQL server解决方法
    day 56 linux的安装python3 ,虚拟环境,mysql ,redis
    day55 linux 基础以及系统优化
    Codeforces 989 P循环节01构造 ABCD连通块构造 思维对云遮月参考系坐标轴转换
    Codeforces 990 调和级数路灯贪心暴力 DFS生成树两子树差调水 GCD树连通块暴力
  • 原文地址:https://www.cnblogs.com/sunday294/p/9301584.html
Copyright © 2011-2022 走看看