scrapy-redis大概的架构:

从redis中拉url,构造Request对象,写入SCHEDULER_QUEUE_CLASS定义的队列中,调度器从队列中拉取Request进行抓取

想自定义Request的初衷主要是为了减少内存的占用,当然虽然我们的内存消耗的也不是那么多,也就几个G

scrapy自带的几个队列有这么几个:

* scrapy_redis.queue.SpiderQueue:队列。先入先出队列,先放入Redis的请求优先爬取;
* scrapy_redis.queue.SpiderStack:栈。后放入Redis的请求会优先爬取;
* scrapy_redis.queue.SpiderPriorityQueue:优先级队列。根据优先级算法计算哪个先爬哪个后爬,比较麻烦

简单看下PriorityQueue的源码:

class PriorityQueue(Base):def __len__(self):return self.server.zcard(self.key)def push(self, request):data = self._encode_request(request)score = -request.priorityself.server.execute_command('ZADD', self.key, score, data)def pop(self, timeout=0):pipe = self.server.pipeline()pipe.multi()pipe.zrange(self.key, 0, 0).zremrangebyrank(self.key, 0, 0)results, count = pipe.execute()if results:return self._decode_request(results[0])

其中的_encode_request就是对request对象进行序列化,而_decode_request是对request对象进行反序列化

跟踪下去,其实可以发现,它把整个request对象都进行了序列化存储,然而我们其实只需要url和callback就行, 另外我们其实不需要优先级队列,我们的url也没有优先级顺序,可以改用list

所以我重写了一个队列:

#-*- coding:utf8 -*-from scrapy_redis.queue import Base
from scrapy.utils.reqser import request_to_dict, request_from_dict, _find_method
from scrapy.http import Request
import sysclass SimpleSpiderQueue(Base):def __len__(self):return self.server.llen(self.key)def push(self, request):url = request.urlcb = request.callbackif callable(cb):cb = _find_method(self.spider, cb)data = '%s-*-%s' % (url, cb)self.server.lpush(self.key, data)else:self.server.lpush(self.key, url)def pop(self, timeout=0):if timeout > 0:data = self.server.brpop(self.key, timeout=timeout)if isinstance(data, tuple):data = data[1]else:data = self.server.rpop(self.key)if data:p = data.split('-*-')try:if len(p) == 2:nurl = p[0]cb = p[1]cb = getattr(self.spider, str(cb))return Request(url=nurl, callback=cb)else:nurl = p[0]return Request(url=nurl)except AttributeError as e:raise ValueError("Method %r not found in: %s" % (cb, self.spider))

代码中考虑了有callback和没有callback两种情况

有callback,则缓存的数据为:

url-*-callback

没有callback时,只缓存url

url

此外,我们需要在settings.py中配置上我们自定义的队列

SCHEDULER_QUEUE_CLASS = 'CrawlBaiduMobile.simple_queue.SimpleSpiderQueue'
SCHEDULER_QUEUE_KEY = '%(spider)s:requests'

用了这种缓存策略后,整个内存占用减少了一半以上

scrapy自定义Request的缓存策略(减少内存占用)相关推荐

  1. Delphi FMX正确加载图片最大限度减少内存占用(之一TBitmapSurface)

    Delphi FMX正确加载图片最大限度减少内存占用(之一TBitmapSurface) 国庆前,无意间发现App内存占用陡增,发现是几张4K图片(7680x4320像素)加载引发的(TImage.B ...

  2. Delphi FMX正确加载图片最大限度减少内存占用(之二TImageList)

    Delphi FMX正确加载图片最大限度减少内存占用(之二TImageList) 继上篇<Delphi FMX正确加载图片最大限度减少内存占用(之一TBitmapSurface)>之后,我 ...

  3. 安卓开发笔记——关于图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)...

    在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价--流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...

  4. 【Android 内存优化】Bitmap 内存缓存 ( Bitmap 缓存策略 | LruCache 内存缓存 | LruCache 常用操作 | 工具类代码 )

    文章目录 一.Bitmap 内存缓存策略 二.LruCache 内存缓存 三.LruCache 常用操作 四.LruCache 工具类 五.源码及资源下载 官方参考 : Google 官方提供的 内存 ...

  5. java 减少内存_java中减少内存占用小技巧

    Java做的系统给人的印象是什么?占内存!说道这句话就会有N多人站出来为java辩护,并举出一堆的性能测试报告来证明这一点. 其实从理论上来讲java做的系统并不比其他语言开发出来的系统更占用内存,那 ...

  6. Win10 减少内存占用; google浏览器器减少CPU占用

    减少Win10内存占用 关闭快速启动 google Chrome 系统自动更新 桌面窗口管理器 Antimalwar Service Excultable 方法一 方法二 结果 关闭快速启动 平时使用 ...

  7. 关于SetProcessWorkingSetSize减少内存占用 的错误理解

    一.C# Winform应用程序占用内存较大解决方法整理(转) 原文:  http://www.jb51.net/article/56682.htm 背景: 微软的 .NET FRAMEWORK 现在 ...

  8. idea 启动多个项目 减少内存占用

    项目采用 spring boot 和spring cloud 框架,多个模块同时启动时 消耗内存过大,导致电脑崩溃.网上找到减少内存消耗的方法,在此记录一下.参考了https://blog.csdn. ...

  9. SetProcessWorkingSetSize减少内存占用

    系统启动起来以后,内存占用越来越大,使用析构函数.GC.Collect什么的也不见效果,后来查了好久,找到了个办法,就是使用 SetProcessWorkingSetSize函数.这个函数是Windo ...

最新文章

  1. 树莓派3b+找不到wlan0官方解决方案
  2. Java中有哪些无锁技术来解决并发问题?如何使用?
  3. 【AGC005F】Many Easy Problems (NTT)
  4. sublime 自定义快捷键
  5. Intellij Idea插件利器推荐大全
  6. mysql三表联合更新_mysql三表连接update
  7. 台式计算机视频设备打不开,电脑视频设备被占用未能创建视频预览怎么办
  8. AB Micro800编程环境CCW安装
  9. ASP + SQL Server聊天室设计实例
  10. adb shell dumpsys activity top
  11. PDF页面旋转怎么操作
  12. 《股票大作手操盘术--杰西.利弗莫尔》
  13. Cadence Allegro如何设置差分对
  14. 在线音乐播放地址//歌曲URL地址提取
  15. zend framework 1.5.2 中实现梅花雪1.0树状菜单
  16. sql语句date函数
  17. git push报错 protocol error: bad line length character: Acti
  18. 脉冲宽度调制(SPWM)Simulink仿真教程
  19. mysql 军规_58到家MySQL军规升级版
  20. SQLite数据库的下载及安装步骤

热门文章

  1. C++/CLI思辨录之再谈继承
  2. AspNetCore 使用NLog日志,NLog是基于.NET平台开的类库!(又一神器)
  3. [USACO17FEB] Why Did the Cow Cross the Road I P (树状数组求逆序对 易错题)
  4. idea 配置maven一直停留在loading archetype list
  5. Spring MVC Converter(类型转换器)详解
  6. lvs web服务器不响应,lvs web服务器不响应
  7. ip变更 mysql无法启动_MySQL 重装MySQL后, mysql服务无法启动
  8. 华为大佬:做一个快乐的程序员,而不是码农
  9. 组件化思维对于一个UI设计来说有多重要?
  10. 零基础开始学前端有什么建议?