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. Python——socketserver编程(客户端/服务器)

    一.socketserver是标准库中的高级模块,它的目标是简化很多多样板代码,是创建网络客户端和服务器所必须的代码.(事件驱动) 二.模块类 BaseServer :包含核心服务器功能和mix-in ...

  2. [模板] 次短路 | bzoj1726-[Usaco2006Nov]Roadblocks第二短路

    简介 所谓次短路, 顾名思义, 就是第二短路. :P 1到n的次短路长度必然产生于:1到x的最短路 + edge(x,y) + y到n的最短路 简单证明一下: 设 \(dis(i,j)\) 表示 \( ...

  3. Java大小写转化

    java大写转小写 public String toLowerCase(String str){ char[] chars = str.toCharArray(); for (int i = 0; i ...

  4. LoadRunner【第三篇】录制脚本实践:订票网站

    启动服务 安装好loadrunner,我们就可以实践了. loadrunner自带订票网站,可以方便我们练习, 先把下面两个发送到桌面快捷方式 首先,启动服务,点击下面图标(如果服务无法启动,检查端口 ...

  5. zkclient中包引用不对,导致NoSuchMethodError

    nidonglin commented on 31 Oct 2014 Exception in thread "main" java.lang.NoSuchMethodError: ...

  6. python之OpenCv(四)---人脸识别

    对特定图像进行识别,最关键的是要有识别对象的特征文件.OpenCV已经内置了人脸识别特征文件,我们只要使用OpenCV的CascadeClassifier类即可进行识别. 语法: https://gi ...

  7. 安装java8

    很多软件都是在java基础上搭建的 ,所以使用的前提是搭建好java的环境,记录下 linux版本:centos7.2 一.下载 到官网下载最新的java8 链接 注意,因为官网需要同意协议才能下载, ...

  8. 关于设计项目UI界面的软件工具

    关于画UI界面的软件,我在网上找了几个,今天式用这几款软件还可以 1.墨刀:国产的,这个专门画APP界面的,用起来比较简单,有免费版的,要注册才能用,提供云存储,收费版的云存储空间会多一些.网站: h ...

  9. 盒子显隐,伪类边框,盒子阴影,2d平面形变

    -盒子显隐 显隐的盒子尽量不影响其他盒子的布局 display:none; 消失的时候不占位置,显示的时候占位 opacity:0-1; 盒子透明度 overflow: hidden; 超出部分隐藏 ...

  10. [物理学与PDEs]第3章第2节 磁流体力学方程组 2.4 不可压情形的磁流体力学方程组

    不可压情形的磁流体力学方程组 $$\beex \bea \cfrac{\rd {\bf H}}{\rd t}-({\bf H}\cdot\n){\bf u}&=\cfrac{1}{\sigma ...