scrapy-redis是一个基于redis的scrapy组件,通过它可以快速实现简单分布式爬虫程序,该组件本质上提供了三大功能:

  • scheduler - 调度器
  • dupefilter - URL去重规则(被调度器使用)
  • pipeline   - 数据持久化

scrapy-redis组件

1. URL去重

定义去重规则(被调度器调用并应用)

    a. 内部会使用以下配置进行连接Redis

        # 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' b. 去重规则通过redis的集合完成,集合的Key为: key = defaults.DUPEFILTER_KEY % {'timestamp': int(time.time())}
默认配置:
DUPEFILTER_KEY = 'dupefilter:%(timestamp)s' c. 去重规则中将url转换成唯一标示,然后在redis中检查是否已经在集合中存在 from scrapy.utils import request
from scrapy.http import Request req = Request(url='http://www.cnblogs.com/wupeiqi.html')
result = request.request_fingerprint(req)
print(result) # 8ea4fd67887449313ccc12e5b6b92510cc53675c PS:
- URL参数位置不同时,计算结果一致;
- 默认请求头不在计算范围,include_headers可以设置指定请求头
示例:
from scrapy.utils import request
from scrapy.http import Request req = Request(url='http://www.baidu.com?name=8&id=1',callback=lambda x:print(x),cookies={'k1':'vvvvv'})
result = request.request_fingerprint(req,include_headers=['cookies',]) print(result) req = Request(url='http://www.baidu.com?id=1&name=8',callback=lambda x:print(x),cookies={'k1':666}) result = request.request_fingerprint(req,include_headers=['cookies',]) print(result) """
# Ensure all spiders share same duplicates filter through redis.
# DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

2. 调度器

"""
调度器,调度器使用PriorityQueue(有序集合)、FifoQueue(列表)、LifoQueue(列表)进行保存请求,并且使用RFPDupeFilter对URL去重 a. 调度器
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue' # 默认使用优先级队列(默认),其他:PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表)
SCHEDULER_QUEUE_KEY = '%(spider)s:requests' # 调度器中请求存放在redis中的key
SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat" # 对保存到redis中的数据进行序列化,默认使用pickle
SCHEDULER_PERSIST = True # 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
SCHEDULER_FLUSH_ON_START = True # 是否在开始之前清空 调度器和去重记录,True=清空,False=不清空
SCHEDULER_IDLE_BEFORE_CLOSE = 10 # 去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
SCHEDULER_DUPEFILTER_KEY = '%(spider)s:dupefilter' # 去重规则,在redis中保存时对应的key
SCHEDULER_DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'# 去重规则对应处理的类 """
# Enables scheduling storing requests queue in redis.
SCHEDULER = "scrapy_redis.scheduler.Scheduler" # Default requests serializer is pickle, but it can be changed to any module
# with loads and dumps functions. Note that pickle is not compatible between
# python versions.
# Caveat: In python 3.x, the serializer must return strings keys and support
# bytes as values. Because of this reason the json or msgpack module will not
# work by default. In python 2.x there is no such issue and you can use
# 'json' or 'msgpack' as serializers.
# SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat" # Don't cleanup redis queues, allows to pause/resume crawls.
# SCHEDULER_PERSIST = True # Schedule requests using a priority queue. (default)
# SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue' # Alternative queues.
# SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.FifoQueue'
# SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.LifoQueue' # Max idle time to prevent the spider from being closed when distributed crawling.
# This only works if queue class is SpiderQueue or SpiderStack,
# and may also block the same time when your spider start at the first time (because the queue is empty).
# SCHEDULER_IDLE_BEFORE_CLOSE = 10  

3. 数据持久化

2. 定义持久化,爬虫yield Item对象时执行RedisPipeline

    a. 将item持久化到redis时,指定key和序列化函数

        REDIS_ITEMS_KEY = '%(spider)s:items'
REDIS_ITEMS_SERIALIZER = 'json.dumps' b. 使用列表保存item数据

4. 起始URL相关

"""
起始URL相关 a. 获取起始URL时,去集合中获取还是去列表中获取?True,集合;False,列表
REDIS_START_URLS_AS_SET = False # 获取起始URL时,如果为True,则使用self.server.spop;如果为False,则使用self.server.lpop
b. 编写爬虫时,起始URL从redis的Key中获取
REDIS_START_URLS_KEY = '%(name)s:start_urls' """
# If True, it uses redis' ``spop`` operation. This could be useful if you
# want to avoid duplicates in your start urls list. In this cases, urls must
# be added via ``sadd`` command or you will get a type error from redis.
# REDIS_START_URLS_AS_SET = False # Default start urls key for RedisSpider and RedisCrawlSpider.
# REDIS_START_URLS_KEY = '%(name)s:start_urls'

scrapy-redis示例

# DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
#
#
# from scrapy_redis.scheduler import Scheduler
# from scrapy_redis.queue import PriorityQueue
# SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue' # 默认使用优先级队列(默认),其他:PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表)
# SCHEDULER_QUEUE_KEY = '%(spider)s:requests' # 调度器中请求存放在redis中的key
# SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat" # 对保存到redis中的数据进行序列化,默认使用pickle
# SCHEDULER_PERSIST = True # 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
# SCHEDULER_FLUSH_ON_START = False # 是否在开始之前清空 调度器和去重记录,True=清空,False=不清空
# SCHEDULER_IDLE_BEFORE_CLOSE = 10 # 去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
# SCHEDULER_DUPEFILTER_KEY = '%(spider)s:dupefilter' # 去重规则,在redis中保存时对应的key
# SCHEDULER_DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'# 去重规则对应处理的类
#
#
#
# REDIS_HOST = '10.211.55.13' # 主机名
# 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'

配置文件

import scrapy

class ChoutiSpider(scrapy.Spider):
name = "chouti"
allowed_domains = ["chouti.com"]
start_urls = (
'http://www.chouti.com/',
) def parse(self, response):
for i in range(0,10):
yield

爬虫文件

 
 
 

scrapy-redis的使用与解析的更多相关文章

  1. Scrapy框架的架构原理解析

    爬虫框架--Scrapy 如果你对爬虫的基础知识有了一定了解的话,那么是时候该了解一下爬虫框架了.那么为什么要使用爬虫框架? 学习框架的根本是学习一种编程思想,而不应该仅仅局限于是如何使用它.从了解到 ...

  2. Netty开发redis客户端,Netty发送redis命令,netty解析redis消息

    关键字:Netty开发redis客户端,Netty发送redis命令,netty解析redis消息, netty redis ,redis RESP协议.redis客户端,netty redis协议 ...

  3. 曹工说Redis源码(5)-- redis server 启动过程解析,以及EventLoop每次处理事件前的前置工作解析(下)

    曹工说Redis源码(5)-- redis server 启动过程解析,eventLoop处理事件前的准备工作(下) 文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis ...

  4. Scrapy+redis实现分布式爬虫

    概述 什么是分布式爬虫 需要搭建一个由n台电脑组成的机群,然后在每一台电脑中执行同一组程序,让其对同一网络资源进行联合且分布的数据爬取. 原生Scrapy无法实现分布式的原因 原生Scrapy中调度器 ...

  5. 基于Python,scrapy,redis的分布式爬虫实现框架

    原文  http://www.xgezhang.com/python_scrapy_redis_crawler.html 爬虫技术,无论是在学术领域,还是在工程领域,都扮演者非常重要的角色.相比于其他 ...

  6. scrapy爬虫框架setting模块解析

    平时写爬虫的时候并不需要设置setting里所有的参数,今天心血来潮,花了点时间查了一下setting模块创建后自动写入的所有参数的含义,记录一下. 模块相关说明信息 # -*- coding: ut ...

  7. Scrapy框架的执行流程解析

    这里主要介绍七个大类Command->CrawlerProcess->Crawler->ExecutionEngine->sceduler另外还有两个类:Request和Htt ...

  8. python 全栈开发,Day101(redis操作,购物车,DRF解析器)

    昨日内容回顾 1. django请求生命周期? - 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端 请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者po ...

  9. 曹工说Redis源码(2)-- redis server 启动过程解析及简单c语言基础知识补充

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

  10. Golang 实现 Redis(11): RDB 文件解析

    RDB 文件使用二进制方式存储 Redis 内存中的数据,具有体积小.加载快的优点.本文主要介绍 RDB 文件的结构和编码方式,并借此探讨二进制编解码和文件处理方式,希望对您有所帮助. 本文基于 RD ...

随机推荐

  1. Linux同时安装python2和Python3

    我们以Ubuntu 为例,默认地,Linux安装好后会默认安装python2版本: 安装Python3: For Debian:   [user@host]$ sudo apt-get install ...

  2. JSP求和计算

    已知两个数的值,如何求和并输出? <%@ page language="java" import="java.util.*,java.text.*" co ...

  3. symfony window下的安装 安装时候出现的问题以及解决方案

    1. cmd进入DOS  , cd 到 php.exe 的目录下 2.         php -r "readfile('http://symfony.com/installer');&q ...

  4. Android ROM 打包记录

    android5.1平板或手机应用层一些常用的修改项及目录所在: 1.所以系统应用所在的目录: \alps\packages\apps 2.一些系统属性的定义:并且可以仿写自行定义变量 \alps\b ...

  5. JQuery Mobile难点备忘

    1 固定header: data-position="fixed",如果仅仅是加了这个属性,当页面出现滚动条的时候点击页面内容,header还是会隐藏显示全屏,如果不需要这样,加入 ...

  6. SpringMVC由浅入深day02_7上传图片

    7 上传图片 7.1 需求 在修改商品页面,添加上传商品图片功能. 7.2 springmvc中对多部件类型解析 在页面form中提交enctype="multipart/form-data ...

  7. Extjs定义的Fckeditor控件

    Ext.namespace('CRM.Panels'); //Ext.BoxComponent 这里继承是参考的Ext.form.Field CRM.Panels.Fckeditor = Ext.ex ...

  8. windows应急响应入侵排查思路

    0x00 前言 ​ 当企业发生黑客入侵.系统崩溃或其它影响业务正常运行的安全事件时,急需第一时间进行处理,使企业的网络信息系统在最短时间内恢复正常工作,进一步查找入侵来源,还原入侵事故过程,同时给出解 ...

  9. Unity Shader 设置纹理采样tex2D过滤方式

    双击红色框区域

  10. 脚本控制animation的事件

    由于动作设计经常修改动作,所以每次改完都要再添加一次animation的事件,所以就直接写了个脚本,当然以后可以做成表格,然后用脚本从表格中读取,然后生成对应的animation事件.在Assets/ ...