#scrapy-redis--->queue.py-->class FifoQueue 队列 LifoQueue(lastinfirstout栈)

#self.server父类Base中链接字符串 ---》 LifoQueue _encode_reques---》Base---》_encode_request--》serializer--->picklecompat

#picklecompat-->/usr/local/lib/python3.6/site-packages/scrapy_redis/picklecompat.py
# def loads(s):
# return pickle.loads(s)
#
#
# def dumps(obj):
# return pickle.dumps(obj, protocol=-1) #通过pickle做的serializer #server来源
#/usr/local/lib/python3.6/site-packages/scrapy_redis/connection.py # 通过 def get_redis---》defaults.REDIS_CLS--》/usr/local/lib/python3.6/site-packages/scrapy_redis/defaults.py
#redis.StrictRedis--># import redis #redis.Redis --->/usr/local/lib/python3.6/site-packages/redis/client.py --->redis继承了 StrictRedis #def get_redis
# if url:
# return redis_cls.from_url(url, **kwargs)
# else:
# return redis_cls(**kwargs)
# 有url通过url实例化 没有url就直接加括号实例化--》拿到server #调度器
#/usr/local/lib/python3.6/site-packages/scrapy_redis/scheduler.py
#def enqueue_request--->self.queue.push(request) 放东西
#def next_request -----request = self.queue.pop(block_pop_timeout) 取东西
#def enqueue_request--->self.df.request_seen(request)判断是否存在
#/usr/local/lib/python3.6/site-packages/scrapy_redis/dupefilter.py def request_seen
#self.server.sadd往集合里添加 根据self.server.sadd的返回值True就是如果是0就没加进去就是有已经添加了,如果是1就是没看到过并添加了 #这里面
#/usr/local/lib/python3.6/site-packages/scrapy_redis/queue.py LifoQueue pop push # #dupefilter.py pipelines.py scheduler.py是组件里做的事
#default.py默认值
#picklecompat.py用什么进行序列化
#scheduler.py调用的queue.py #spiders.py爬虫 def start_requests--》self.next_requests
# use_set = self.settings.getbool('REDIS_START_URLS_AS_SET', defaults.START_URLS_AS_SET)
# fetch_one = self.server.spop if use_set else self.server.lpop
#就是去redis取启始url 如果用spiders就需要redis中预先存好启始url 如果不用这个spider我们自己需要手动添加启始url
#
#utiles公共的 #链接redis
#如果有url url优先链接 否则就是ip
# 配置到settings里面
#http://www.cnblogs.com/wupeiqi/articles/6912807.html # REDIS_HOST = 'localhost' # 主机名
# 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' #调度器配置
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue' # 默认使用优先级队列(默认),其他:PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表)
SCHEDULER_QUEUE_KEY = '%(spider)s:requests' # 调度器中请求存放在redis中的key
# v='%(spider)s:requests'
# val=v%{'spider':'hahah'}
# val
# 'hahah:requests'
#每个爬虫,都有自己在scrapy-redis中的队列,在redis中对应的一个key
#renjian:requests:{}/[] 选择是{}/[]是根据PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表) 来定的 #放任务的
#renjian:requests:['http://www.baidu.com',]
#jianren:requests:['http://www.chouti.com',]
#/Users/shuanggai/PycharmProjects/git/python/D20171113/scrapy-redis/day115/dabo/dabo/spiders/renjian.py中的name = 'renjian' 用于做格式化 # SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat" # 对保存到redis中的数据进行序列化,默认使用pickle
# SCHEDULER_PERSIST = True # 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
# 测试时清空 线上不清空
# SCHEDULER_FLUSH_ON_START = True # 是否在开始之前清空 调度器和去重记录,True=清空,False=不清空
# SCHEDULER_IDLE_BEFORE_CLOSE = 10 # 去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
#/usr/local/lib/python3.6/site-packages/scrapy_redis/scheduler.py--》def next_request --》self.idle_before_close
#idle_before_close=0,默认是0
#/usr/local/lib/python3.6/site-packages/scrapy_redis/queue.py-->def pop-->data = self.server.blpop(self.key, timeout)
#lpop取回的是元祖 超时就是体现在这里 # SCHEDULER_DUPEFILTER_KEY = '%(spider)s:dupefilter' # 去重规则,在redis中保存时对应的key
# SCHEDULER_DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter' # 去重规则对应处理的类
#访问记录 类型是集合
#/usr/local/lib/python3.6/site-packages/scrapy_redis/dupefilter.py
#def request_seen ---》self.server.sadd
"""
renjian:dupefilter:{}
jianren:dupefilter:{}
"""
#/usr/local/lib/python3.6/site-packages/scrapy_redis/dupefilter.py --》def request_seen---》fp = self.request_fingerprint(request)
#/usr/local/lib/python3.6/site-packages/scrapy/utils/request.py--》def request_fingerprint(request, include_headers=None):
from scrapy.utils.request import request_fingerprint
from scrapy.http import Request
r1=Request(url='http://www.baidu.com?id=1&page=2',headers={'k1':'v1'})
r1_str = request_fingerprint(r1,include_headers=['k1']) #把对象转化成字符串
print(r1_str) #75d6587d87b3f4f3aa574b33dbd69ceeb9eafe7b
r2=Request(url='http://www.baidu.com?page=2&id=1',headers={'k1':'v2'})
r2_str = request_fingerprint(r2,include_headers=['k1'])
print(r2_str)
#默认 是否加请求头和参数位置不同不影响值,但是参数的增加或减少会影响值 除非添加include_headers #重要
## 利用调度器使用scrapy_redis
SCHEDULER="scrapy_redis.scheduler.Scheduler"
#去重的记录使用scrapy_redis
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" #数据持久化
# from scrapy_redis.pipelines import RedisPipeline
# ITEM_PIPELINES = {
# 'dabo.pipelines.DaboPipeline': 300,
# 'dabo.pipelines.XiaoboPipeline': 400,
# }
from scrapy_redis.pipelines import RedisPipeline
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 300,
}
REDIS_ITEMS_KEY = '%(spider)s:items'
REDIS_ITEMS_SERIALIZER = 'json.dumps' #启始url
REDIS_START_URLS_AS_SET = False
#True就是集合False就是列表
REDIS_START_URLS_KEY = '%(name)s:start_urls' #/usr/local/lib/python3.6/site-packages/scrapy_redis/spiders.py 获取start_url 所以需要在redis先添加url
#def start_requests-->self.next_requests
# use_set = self.settings.getbool('REDIS_START_URLS_AS_SET', defaults.START_URLS_AS_SET)
# fetch_one = self.server.spop if use_set else self.server.lpop
#conn.lpush('renjian:start_urls','http://www.chouti.com') #/usr/local/lib/python3.6/site-packages/scrapy_redis/pipelines.py--->class RedisPipeline-->def process_item-->deferToThread(self._process_item, item, spider) # class Base(object):
# """Per-spider base queue class"""
#
# def __init__(self, server, spider, key, serializer=None):
# """Initialize per-spider redis queue.
#
# Parameters
# ----------
# server : StrictRedis
# Redis client instance.
# spider : Spider
# Scrapy spider instance.
# key: str
# Redis key where to put and get messages.
# serializer : object
# Serializer object with ``loads`` and ``dumps`` methods.
#
# """
# if serializer is None:
# # Backward compatibility.
# # TODO: deprecate pickle.
# serializer = picklecompat
# if not hasattr(serializer, 'loads'):
# raise TypeError("serializer does not implement 'loads' function: %r"
# % serializer)
# if not hasattr(serializer, 'dumps'):
# raise TypeError("serializer '%s' does not implement 'dumps' function: %r"
# % serializer)
#
# self.server = server
# self.spider = spider
# self.key = key % {'spider': spider.name}
# self.serializer = serializer
#
# def _encode_request(self, request):
# """Encode a request object"""
# obj = request_to_dict(request, self.spider)
# return self.serializer.dumps(obj) # class LifoQueue(Base):
# """Per-spider LIFO queue."""
#
# def __len__(self):
# """Return the length of the stack"""
# return self.server.llen(self.key)
#
# def push(self, request):
# """Push a request"""
# self.server.lpush(self.key, self._encode_request(request))
#
# def pop(self, timeout=0):
# """Pop a request"""
# if timeout > 0:
# data = self.server.blpop(self.key, timeout)
# if isinstance(data, tuple):
# data = data[1]
# else:
# data = self.server.lpop(self.key)
#
# if data:
# return self._decode_request(data)
#
#
#
# if serializer is None:
# # Backward compatibility.
# # TODO: deprecate pickle.
# serializer = picklecompat
# if not hasattr(serializer, 'loads'):
# raise TypeError("serializer does not implement 'loads' function: %r"
# % serializer)
# if not hasattr(serializer, 'dumps'):
# raise TypeError("serializer '%s' does not implement 'dumps' function: %r"
# % serializer)
# def get_redis(**kwargs):
# """Returns a redis client instance.
#
# Parameters
# ----------
# redis_cls : class, optional
# Defaults to ``redis.StrictRedis``.
# url : str, optional
# If given, ``redis_cls.from_url`` is used to instantiate the class.
# **kwargs
# Extra parameters to be passed to the ``redis_cls`` class.
#
# Returns
# -------
# server
# Redis client instance.
#
# """
# redis_cls = kwargs.pop('redis_cls', defaults.REDIS_CLS)
# url = kwargs.pop('url', None)
# if url:
# return redis_cls.from_url(url, **kwargs)
# else:
# return redis_cls(**kwargs)

  

scrapy-redis源码抛析的更多相关文章

  1. vue.js源码精析

    MVVM大比拼之vue.js源码精析 VUE 源码分析 简介 Vue 是 MVVM 框架中的新贵,如果我没记错的话作者应该毕业不久,现在在google.vue 如作者自己所说,在api设计上受到了很多 ...

  2. 30s源码刨析系列之函数篇

    前言 由浅入深.逐个击破 30SecondsOfCode 中函数系列所有源码片段,带你领略源码之美. 本系列是对名库 30SecondsOfCode 的深入刨析. 本篇是其中的函数篇,可以在极短的时间 ...

  3. 曹工说Redis源码(4)-- 通过redis server源码来理解 listen 函数中的 backlog 参数

    文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis,而怎么才能懂,光看是不够的,建议跟着下面的这一篇,把环境搭建起来,后续可以自己阅读源码,或者跟着我这边一起阅读.由于 ...

  4. redis源码学习之lua执行原理

    聊聊redis执行lua原理 从一次面试场景说起   "看你简历上写的精通redis" "额,还可以啦" "那你说说redis执行lua脚本的原理&q ...

  5. MVVM大比拼之AngularJS源码精析

    MVVM大比拼之AngularJS源码精析 简介 AngularJS的学习资源已经非常非常多了,AngularJS基础请直接看官网文档.这里推荐几个深度学习的资料: AngularJS学习笔记 作者: ...

  6. MVVM大比拼之knockout.js源码精析

    简介 本文主要对源码和内部机制做较深如的分析,基础部分请参阅官网文档. knockout.js (以下简称 ko )是最早将 MVVM 引入到前端的重要功臣之一.目前版本已更新到 3 .相比同类主要有 ...

  7. Redis源码研究--字典

    计划每天花1小时学习Redis 源码.在博客上做个记录. --------6月18日----------- redis的字典dict主要涉及几个数据结构, dictEntry:具体的k-v链表结点 d ...

  8. 一起学习redis源码

    redis的一些介绍,麻烦阅读前面的几篇文章,想对redis的详细实现有所了解,强力推荐<redis设计与实现>(不仅仅从作者那儿学习到redis的实现,还有项目的管理.思想等,作者可能比 ...

  9. Redis源码分析系列

    0.前言 Redis目前热门NoSQL内存数据库,代码量不是很大,本系列是本人阅读Redis源码时记录的笔记,由于时间仓促和水平有限,文中难免会有错误之处,欢迎读者指出,共同学习进步,本文使用的Red ...

随机推荐

  1. centos6.5 安装JDK

    今天在自己的centos机子上安装jdk,发现以前的教程都比较旧了,很多东西都过时了.今天把自己安装的感受写一下. 判断是否安装 首先,我们得判断机子上是不是安装了jdk,好多人推荐使用java -v ...

  2. Python创建插入数据库MySQL

    首先要在控制台创建好数据库 mysql -u root -p 创建数据库 查看数据库 -------------------更新分割线(上面为新增...太久没用都忘了SQL基本命令了)-------- ...

  3. (转) 一次批量重启引发的Neutron网络故障

    现场回顾 故事发生于某个下午,采用 salt 更新某集群的 neutron.conf (log 相关配置项) 并批量重启 neutron-openvswitch-agent(以下简称 neutron- ...

  4. 判断一个浏览器是否支持opacity

    支持opacity的浏览器,总会将opacity值规范成小于1.0且以0开头的值.例如,如果将opacity指定为:.5,原始支持opacity的浏览器就会将该值规范为0.5,而不支持opacity的 ...

  5. 原生js实现用鼠标画图

    代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  6. [软件工程基础]团队作业Week3

    团队介绍 团队名:弗朗明哥舞步 团队角色 开发:杨艺媛,易子沐,赵晓宇,夏欣怡 测试:张华杰 PM:刘斯盾 刘斯盾 我是刘斯盾,喜欢编程,喜欢运动!很高兴和大家一起开发这个项目! 杨艺媛 我叫杨艺媛, ...

  7. GEF入门实例_总结_06_为编辑器添加内容

    一.前言 本文承接上一节:GEF入门实例_总结_05_显示一个空白编辑器 在上一节我们为我们的插件添加了一个空白的编辑器,这一节我们将为此编辑器添加内容. 二.GEF的MVC模式 在此只简单总结一下, ...

  8. UVALive 3635 Pie(二分法)

    简单的二分法应用,循环1000次精度就满足要求了. #include<iostream> #include<cstdio> #include<cstdlib> #i ...

  9. uva1583(暴力枚举或打表)

    紫书上的代码是打表. 我的做法是暴力枚举.注意,有多个变量时,选择枚举哪一个变量会影响到时间效率,值得考虑.由于各位数字之和最大就是五个9的和为45,所以就枚举各位数字之和比较快. #include& ...

  10. [基本操作] kd 树

    概念就不说了吧,网上教程满天飞 学了半天才知道,kd 树实质上只干了两件事情: 1.快速定位一个点 / 矩形 2.有理有据地优化暴力 第一点大概是可以来做二维平面上给点/矩形打标记的问题 第二点大概是 ...