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 struct import redis def 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'%name
for 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'%name
queue_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 = 0
while True:
if f.tell() == SIZE_SIZE:
break
f.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 += 1
print('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 = ''
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.运行结果

scrapy_redis 相关: 将 jobdir 保存的爬虫进度转移到 Redis的更多相关文章

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

    使用git stash命令保存和恢复进度 git stash 保存当前工作进度,会把暂存区和工作区的改动保存起来.执行完这个命令后,在运行git status命令,就会发现当前是一个干净的工作区,没有 ...

  2. git stash 保存和恢复进度

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

  3. scrapy_redis 相关: 查看保存的数据

    0.参考资料 https://redis.io/topics/data-types-intro An introduction to Redis data types and abstractions ...

  4. scrapy_redis 相关: 多线程更新 score/request.priority

    0.背景 使用 scrapy_redis 爬虫, 忘记或错误设置 request.priority(Rule 也可以通过参数 process_request 设置 request.priority), ...

  5. Post请求data参数构造及巧用js脚本显示爬虫进度

    小爬最近随着对python中字符串.json等理解进一步加深,发现先前我随笔中提到的data构造和传参方法略复杂,原本有更简单的方法,Mark如下. 先前小爬我使用的requests.post请求中d ...

  6. iPhone/iOS图片相关(读取、保存、绘制、其它相关)

    http://blog.csdn.net/jerryvon/article/details/7526147 20:50:42 一.读取图片 1.从资源(resource)读取 UIImage* ima ...

  7. Agumater 爬虫进度带上了百分比,消除了.0

  8. scrapy分布式爬虫scrapy_redis一篇

    分布式爬虫原理 首先我们来看一下scrapy的单机架构:     可以看到,scrapy单机模式,通过一个scrapy引擎通过一个调度器,将Requests队列中的request请求发给下载器,进行页 ...

  9. Scrapy 框架,爬虫文件相关

    Spiders 介绍 由一系列定义了一个网址或一组网址类如何被爬取的类组成 具体包括如何执行爬取任务并且如何从页面中提取结构化的数据. 简单来说就是帮助你爬取数据的地方 内部行为 #1.生成初始的Re ...

随机推荐

  1. QT出现应用程序无法正常启动0xc000007b的错误

    最近做了一个成绩管理系统,打包好后,运行他的exe可执行文件时,出现了如下图的错误提示: 在网上查阅了很多资料,其中有篇文章给了我很大的启示和帮助,文章地址http://www.cnblogs.com ...

  2. 【XSY2962】作业 数学

    题目描述 有一个递推式: \[ \begin{align} f_0&=1-\frac{1}{e}\\ f_n&=1-nf_{i-1} \end{align} \] 求 \(f_n\) ...

  3. unix文件系统中的硬链接和软连接

    硬链接: 一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名.但是,Unix/Linux系统允许,多个文件名指向同一个inode号码. 这意味着 ...

  4. Java【第七篇】面向对象之类设计

    Java类的继承 类继承语法规则 < 修饰符> class < 子类名称> [extends < 父类>] { <属性和方法的声明> }  类的继承 子 ...

  5. 修改已有git仓库的远程仓库指向

    $ git remote set-url origin git@github.com:test/thinkphp.git 或者 $ git config -e 直接编辑其中origin的url就行了, ...

  6. Spring security oauth2 client_credentials认证 最简单示例代码

    基于spring-boot-2.0.0 1,在pom.xml中添加: <!-- security --> <!-- https://mvnrepository.com/artifac ...

  7. busybox(四)完善

    目录 busybox(四)完善 proc挂载 手动挂载 proc解析 使用脚本自动挂载 使用mount-a挂载 udev/mdev 挂载 使用jffs2 文件系统格式 安装zlib 安装jffs2 生 ...

  8. 异步请求之ajax

    一.初识ajax 1.下载引入jQuery <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"& ...

  9. css长度单位学习(em,rem,px,vw,vh)

    绝对长度单位 绝对长度单位代表一个物理测量 [像素px(pixels)] 像素,为影像显示的基本单位,译自英文"pixel",pix是英语单词picture的常用简写,加上英语单词 ...

  10. IDEA15 下运行Scala遇到问题以及解决办法

    为了让Scala运行起来还是很麻烦,为了大家方便,还是记录下来: 1.首先我下载的是IDEA的社区版本,版本号为15. 2.下载安装scala插件: 2.1 进入设置菜单. 2.2 点击安装JetBr ...