0.参考

Scrapy 隐含 bug: 强制关闭爬虫后从 requests.queue 读取的已保存 request 数量可能有误

1.说明

Scrapy 设置 jobdir,停止爬虫后,保存文件目录结构:

crawl/apps/
├── requests.queue
│   ├── active.json
│   ├── p0
│   └── p1
├── requests.seen
└── spider.state

requests.queue/p0 文件保存 priority=0 的未调度 request, p-1 对应实际 priority=1 的高优先级 request,转移到 redis 有序集合时,score 值越小排序越靠前,因此取 score 为 -1。以此类推,p1 对应 priority=-1 的低优先级 request。

requests.seen 保存请求指纹过滤器对已入队 request 的 hash 值,每行一个值。

spider.state 涉及自定义属性的持久化存储,不在本文处理范围以内。

2.实现代码

import os
from os.path import join
import re
import structimport redisdef sadd_dupefilter(jobdir, redis_server, name):"""See python/lib/site-packages/scrapy/dupefilters.py"""file = join(jobdir, 'requests.seen')with open(file) as f:print('Processing %s, it may take minutes...'%file)key = '%s:dupefilter'%namefor x in f:redis_server.sadd(key, x.rstrip())print('Result: {} {}'.format(key, redis_server.scard(key)))def zadd_requests(jobdir, redis_server, name):"""See python/lib/site-packages/queuelib/queue.py"""SIZE_FORMAT = ">L"SIZE_SIZE = struct.calcsize(SIZE_FORMAT)key = '%s:requests'%namequeue_dir = join(jobdir, 'requests.queue')file_list = os.listdir(queue_dir)file_score_dict = dict([(f, int(f[1:])) for f in file_list if re.match(r'^p-?\d+$', f)])for (file, score) in file_score_dict.items():print('Processing %s, it may take minutes...'%file)f = open(join(queue_dir, file), 'rb+')qsize = f.read(SIZE_SIZE)total_size, = struct.unpack(SIZE_FORMAT, qsize)f.seek(0, os.SEEK_END)actual_size = 0while True:if f.tell() == SIZE_SIZE:breakf.seek(-SIZE_SIZE, os.SEEK_CUR)size, = struct.unpack(SIZE_FORMAT, f.read(SIZE_SIZE)) f.seek(-size-SIZE_SIZE, os.SEEK_CUR)data = f.read(size)redis_server.execute_command('ZADD', key, score, data)f.seek(-size, os.SEEK_CUR)actual_size += 1print('total_size {}, actual_size {}, score {}'.format(total_size, actual_size, score))print('Result: {} {}'.format(key, redis_server.zlexcount(key, '-', '+')))if __name__ == '__main__':name = 'test'jobdir = '/home/yourproject/crawl/apps'database_num = 0# apps/# ├── requests.queue# │   ├── active.json# │   ├── p0# │   └── p1# ├── requests.seen# └── spider.state
    password = 'password'host = '127.0.0.1'port = '6379'redis_server = redis.StrictRedis.from_url('redis://:{password}@{host}:{port}/{database_num}'.format(password=password, host=host,port=port, database_num=database_num))sadd_dupefilter(jobdir, redis_server, name)zadd_requests(jobdir, redis_server, name)

3.运行结果

转载于:https://www.cnblogs.com/my8100/p/scrapy_jobdir_to_redis.html

scrapy_redis 相关: 将 jobdir 保存的爬虫进度转移到 Redis相关推荐

  1. Git常用操作(清除工作区未跟踪文件、保存和恢复进度、打标签)

    git clean 清除工作区未跟踪文件 git clean 命令去除冗余文件或者清理工作目录 git clean -f -d 移除工作目录中所有未追踪的文件以及空的子目录.(-f强制删除) git ...

  2. 使用git stash命令保存和恢复进度

    上一篇博客我们使用git checkout命令来切换分支. 我们有时会遇到这样的情况,正在dev分支开发新功能,做到一半时有人过来反馈一个bug,让马上解决,但是新功能做到了一半你又不想提交,这时就可 ...

  3. git stash 强制恢复_git stash 保存和恢复进度

    1. stash当前修改 git stash会把所有未提交的修改(包括暂存的和非暂存的)都保存起来,用于后续恢复当前工作目录. 比如下面的中间状态,通过git stash命令推送一个新的储藏,当前的工 ...

  4. Python 爬虫 性能 相关( asyncio 模块 --- 高性能爬虫 )

    From:https://www.cnblogs.com/bravexz/p/7741633.html 爬虫应用 asyncio 模块 ( 高性能爬虫 ):https://www.cnblogs.co ...

  5. python下载图片并保存_Python爬虫获取图片并下载保存至本地的实例

    1.抓取煎蛋网上的图片. 2.代码如下: import urllib.request import os #to open the url def url_open(url): req=urllib. ...

  6. 用户dsn保存位置‘_苹果iOS 13.6终于能保存文章阅读进度了 朋友都等秃了

    几天前,iOS 13.6 Beta 2和iPadOS 13.6 Beta 2发布,据外媒iPhoneHacks消息,苹果此次通过新软件更新对Apple News应用程序进行了改进,更新后的iOS 13 ...

  7. 使用MemCache进行相关缓存的保存处理

    一. 首先,需要导入相关工具包,xmemcached-1.4.2.jar 为必须导入的工具包. 二. 进行具体工具类的编写工作,下面直接上代码. CacheCallback.java package ...

  8. python requests cookie保存_Python爬虫教程:爬取知乎网

    知乎已经成为了爬虫的训练场,本文利用Python中的requests库,模拟登陆知乎,获取cookie,保存到本地,然后这个cookie作为登陆的凭证,登陆知乎的主页面,爬取知乎主页面上的问题和对应问 ...

  9. scrapy 保存mysql_scrapy爬虫事件以及数据保存为txt,json,mysql

    今天要爬取的网页是虎嗅网 我们将完成如下几个步骤: 创建一个新的Scrapy工程 定义你所需要要抽取的Item对象 编写一个spider来爬取某个网站并提取出所有的Item对象 编写一个Item Pi ...

  10. python批量读取图片并批量保存_Python爬虫:批量抓取花瓣网高清美图并保存

    原标题:Python爬虫:批量抓取花瓣网高清美图并保存 昨天看到了不错的图片分享网--花瓣,里面的图片质量还不错,所以利用selenium+xpath我把它的妹子的栏目下爬取了下来,以图片栏目名称给文 ...

最新文章

  1. 更改SQL 2005登录时的默认数据库
  2. c efcore.mysql_EF Core在mysql中调用存储过程
  3. 【转】多语言的正则表达式,我们应该掌握
  4. 剑指Offer #09 变态跳台阶(数列推导)
  5. XML的序列化和反序列化 详细介绍
  6. Spring Boot——[JPA 无法注入 JpaRepository 子接口问题]解决方案
  7. Windows Server 2008 R2卸载干净ORACLE 11G
  8. TFS命令tf:undo(强制签入签出文件)
  9. juery 常用方法
  10. NetBPM工作流的一个示例-请假审批
  11. layer模态窗简单使用
  12. 如何获取免费比特币?
  13. C++11 chrono库
  14. 数据统计学习的5个基本流程
  15. 设计模式-访问者模式-java-中文版
  16. Java基础案例4-8:模拟物流快递系统程序设计
  17. pdf书籍资源共享_书籍和更多内容已获许可使用知识共享
  18. 创建或打开android模拟器时遇到的问题,以及打开后遇到的Failed to install FragmentTest.apk on device 'emulator-5554': timeout
  19. 使用gulp为项目中的文件自动添加版本号之实践思路
  20. ESP-AT 实践:如何使用两个 ESP32 设备,通过 AT 指令进行 BT SPP 通信?

热门文章

  1. IDEA 的这款插件真是逆天了,代码那都不是事!
  2. 某IT公司的面试题,难度系数“爆表”。。。
  3. 什么是技术驱动型公司?阿里算吗?
  4. Ubuntu16.04 安装Teamviewer
  5. 使用python实现日志功能
  6. python 连接数据库 pymysql模块的使用
  7. 'telent' 不是内部或外部命令,也不是可运行的程序或批处理文件。
  8. Linux XZ压缩格式学习
  9. 2016年6月份那些最实用的 jQuery 插件专辑
  10. C#如何获取物理网卡,虚拟网卡,以及无线网卡