一、scrapy-redis(0.6)依赖的环境

Scrapy >= 1.0.0                #终于过了1版本,这个太重要了,总算坑小了点,感谢那些为了解决各种scrapy与scrapy-redis不兼容做出了贡献的开发者和博主。
redis-py >= 2.10.0
redis server >= 2.8.0

0.6版本的主要更新内容是更新代码以支持Scrapy 1.0; 增加了-a domain=... option for example spiders.

官方源代码

二、scrapy-redis的作用和特点

作用:scrapy-redis为Scrapy提供Redis-backed组件

特点: 可以启动多个爬虫实例共享一个单一的 redis队列。是最适合广泛的多域爬虫。

分布式的post处理。scrapy到的items放入一个redis队列意味着可以分享这个items队列,并在其中启用足够多的post处理进程。

三、scrapy和scrapy-redis的区别与组件的意义

scrapy 是一个通用的爬虫框架
scrapy-redis是为了更方便地实现scrapy分布式爬取,而提供了一些以redis为基础的组件(仅有组件)
scrapy-redis提供了下面四种组件(components):(四种组件意味着这四个模块都要做相应的修改)

Scheduler  Duplication Filter Item PipelineBase Spider

scrapy改造了python本来的collection.deque形成了自己的scrqueue(自己取得名字) 传送门:queuelib/queuelib/queue.py源码
scrapy多个spider不能共享待爬取队列scrqueue, 即scrapy本身不支持爬虫分布式,解决是把这个scrqueue换成redis数据库(也是指redis队列),从同一个redis-server存放要爬取的request,便能让多个spider去同一个数据库里读取。
 
scrapy中跟“待爬队列”直接相关的就是调度器“Scheduler”,它负责对新的request进行入列操作(加入scrqueue),取出下一个要爬取的request(从scrqueue中取出)等操作。它把待爬队列按照优先级建立了一个字典结构,比如:
{
priority0:队列0
priority1:队列2
priority2:队列2
}
然后根据request中的priority属性,来决定该入哪个队列。而出列时,则按priority较小的优先出列。为了管理这个比较高级的队列字典,Scheduler需要提供一系列的方法。原来的Scheduler已经无法使用(被替换掉了,注意上一个红色字段),所以使用scrapy-redis的scheduler组件。
 
scrapy中用集合实现这个request去重功能,scrapy中把已经发送的request指纹放入到一个集合中,把下一个request的指纹拿到集合中比对,如果该指纹存在于集合中,说明这个request发送过了,如果没有则继续操作。(源码传送)这个核心的判重功能是这样实现的:
  1. </pre></div></blockquote><pre name="code" class="plain">def request_seen(self, request):
  2. #self.figerprints就是一个指纹集合
  3. fp = self.request_fingerprint(request)
  4. if fp in self.fingerprints:#这就是判重的核心操作。
  5. return True
  6. self.fingerprints.add(fp)
  7. ......

在scrapy-redis中去重是由Duplication Filter组件来实现的。

四、最快的安装和启用

安装:

  1. $ pip install scrapy-redis
  2. 或者
  3. $ git clone https://github.com/darkrho/scrapy-redis.git
  4. $ cd scrapy-redis
  5. $ python setup.py install

在 settings.py 中启用组件们:

  1. </pre></blockquote><pre name="code" class="plain"># Enables scheduling storing requests queue in redis.
  2. SCHEDULER = "scrapy_redis.scheduler.Scheduler"
  3. </pre></div></blockquote><blockquote style="margin:0 0 0 40px; border:none; padding:0px"><div><span style="white-space:pre"></span><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_16_2220405" name="code" class="python"># Don't cleanup redis queues, allows to pause/resume crawls.
  4. SCHEDULER_PERSIST = True
  5. </pre></div></blockquote><blockquote style="margin:0 0 0 40px; border:none; padding:0px"><div><span style="white-space:pre"></span><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_19_5349541" name="code" class="python"># Schedule requests using a priority queue. (default)
  6. SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderPriorityQueue'
  7. </pre></div></blockquote><blockquote style="margin:0 0 0 40px; border:none; padding:0px"><div><span style="white-space:pre"></span><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_22_4193298" name="code" class="python"># Schedule requests using a queue (FIFO).
  8. SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderQueue'
  9. </pre></div></blockquote><blockquote style="margin:0 0 0 40px; border:none; padding:0px"><div><span style="white-space:pre"></span><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_25_5337568" name="code" class="python"># Schedule requests using a stack (LIFO).
  10. SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderStack'
  11. </pre></div></blockquote><blockquote style="margin:0 0 0 40px; border:none; padding:0px"><div><span style="white-space:pre"></span><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_28_6547876" name="code" class="python"># Max idle time to prevent the spider from being closed when distributed crawling.
  12. # This only works if queue class is SpiderQueue or SpiderStack,
  13. # and may also block the same time when your spider start at the first time (because the queue is empty).
  14. SCHEDULER_IDLE_BEFORE_CLOSE = 10
  15. </pre></div></blockquote><blockquote style="margin:0 0 0 40px; border:none; padding:0px"><div><span style="white-space:pre"></span><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_33_5980278" name="code" class="python"># Store scraped item in redis for post-processing.
  16. ITEM_PIPELINES = {
  17. 'scrapy_redis.pipelines.RedisPipeline': 300
  18. }
  19. </pre></div></blockquote><blockquote style="margin:0 0 0 40px; border:none; padding:0px"><div><span style="white-space:pre"></span><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_38_8651283" name="code" class="python"># Specify the host and port to use when connecting to Redis (optional).
  20. REDIS_HOST = 'localhost'
  21. REDIS_PORT = 6379
  22. </pre></div></blockquote><blockquote style="margin:0 0 0 40px; border:none; padding:0px"><div><span style="white-space:pre"></span><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_42_1638716" name="code" class="python"># Specify the full Redis URL for connecting (optional).
  23. # If set, this takes precedence over the REDIS_HOST and REDIS_PORT settings.
  24. REDIS_URL = 'redis://user:pass@hostname:9001'

五、通过redis来喂饱爬虫们~

scrapy_redis.spiders.RedisSpider类启用了爬虫通过redis得到urls,这些在redis队列中的爬虫将会一个接一个的被处理,!!如果第一个request产生了更多的request,爬虫会先处理这些请求,再从redis队列中抓取其他url。

上面偷懒,这里举个栗子:创建 couxiaoxiao.py

  1. from scrapy_redis.spiders import RedisSpider
  2. </pre></div><div><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_47_2390110" name="code" class="python">class MySpider(RedisSpider):
  3. name = 'myspider'
  4. </pre></div><div><pre code_snippet_id="1682225" snippet_file_name="blog_20160513_50_2662327" name="code" class="python">    def parse(self, response):
  5. # do stuff
  6. pass

运行爬虫

  1. scrapy runspider myspider.py

向redis中装入url们

 
  1. redis-cli lpush myspider:start_urls http://xiaowangzhi.com

scrapy-redis基础和介绍的更多相关文章

  1. Redis项目实战---应用及理论(上)---redis基础知识介绍

    redis(Remote Dictionary Server)   一.原理及特性层面:     1.优势:        1)数据加载在内存中,执行速度快, 数据结构类似于HashMap,HashM ...

  2. Redis基础知识补充及持久化、备份介绍(二)--技术流ken

    Redis知识补充 在上一篇博客<Redis基础认识及常用命令使用(一)--技术流ken>中已经介绍了redis的一些基础知识,以及常用命令的使用,本篇博客将补充一些基础知识以及redis ...

  3. Redis基础知识补充及持久化、备份介绍

    Redis知识补充 在上一篇博客<Redis基础认识及常用命令使用(一)–技术流ken>中已经介绍了redis的一些基础知识,以及常用命令的使用,本篇博客将补充一些基础知识以及redis持 ...

  4. [.net 面向对象程序设计深入](14)Redis——基础

    [.net 面向对象程序设计深入](14)Redis——基础 很长一段时间没更新博客了,坚持做一件事,真不是件容易的事,后面我会继续尽可能的花时间更新完这个系列文章. 因这个系列的文章涉及的范围太大了 ...

  5. [.net 面向对象程序设计深入](36)Redis——基础

    [.net 面向对象程序设计深入](36)Redis——基础 很长一段时间没更新博客了,坚持做一件事,真不是件容易的事,后面我会继续尽可能的花时间更新完这个系列文章. 因这个系列的文章涉及的范围太大了 ...

  6. Redis基础用法、高级特性与性能调优以及缓存穿透等分析

     一.Redis介绍 Redis是一个开源的,基于内存的结构化数据存储媒介,可以作为数据库.缓存服务或消息服务使用.Redis支持多种数据结构,包括字符串.哈希表.链表.集合.有序集合.位图.Hype ...

  7. Redis高级特性介绍及实例分析

    转自:http://www.jianshu.com/p/af7043e6c8f9   Redis基础类型回顾 String Redis中最基本,也是最简单的数据类型.注意,VALUE既可以是简单的St ...

  8. redis基础之python连接redis(五)

    前言 前面介绍了在数据库命令行直接操作redis,现在学习使用python的redis包来操作redis,本人安装的是redis==2.10.6: 系列文章 redis安装和配置 redis命令行操作 ...

  9. REDIS基础笔记

    Redis基础笔记 资源链接 简介 简介 安装 五种数据类型及相应命令 1. 字符串类型 2. 散列类型 3. 列表类型 4. 集合类型 5. 有序集合 其他 事务 SORT 生存时间 任务队列 发布 ...

  10. 消息队列介绍、RabbitMQ&Redis的重点介绍与简单应用

    消息队列介绍.RabbitMQ&Redis的重点介绍与简单应用 消息队列介绍.RabbitMQ.Redis 一.什么是消息队列 这个概念我们百度Google能查到一大堆文章,所以我就通俗的讲下 ...

随机推荐

  1. JAVA I/O(三)内存映射文件

    <Java编程思想>中对内存映射文件有详细的介绍,此处仅做简单记录和总结.内存映射文件允许创建和修改因为太大而不能放入内存的文件. 1. 内存映射文件简单实例 import java.io ...

  2. getContext,getApplicationContext和this有什么区别

    使用this, 说明当前类是context的子类,一般是activity application等使用getApplicationContext 取得的是当前app所使用的application,这在 ...

  3. HDU 1285 确定比赛名次(拓扑排序)题解

    Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委 ...

  4. spring boot 修改Tomcat端口

    package com.tsou.Controller; import org.springframework.boot.*; import org.springframework.boot.auto ...

  5. Java Collections Framework概览

    本文github地址 概览 容器,就是可以容纳其他Java对象的对象.Java Collections Framework(JCF)为Java开发者提供了通用的容器,其始于JDK 1.2,优点是: 降 ...

  6. 论文笔记——Rethinking the Inception Architecture for Computer Vision

    1. 论文思想 factorized convolutions and aggressive regularization. 本文给出了一些网络设计的技巧. 2. 结果 用5G的计算量和25M的参数. ...

  7. [shiro] - 加入rememberMe功能

    shiro不加入rememberMe没事,一加入就出错. RememberMeAuthenticationToken : public interface RememberMeAuthenticati ...

  8. Ubuntu 上 执行命令 java -version 显示 没有那个文件或目录

    解决方法 执行 which java 发现默认java目录:/usr/bin/java . 查看 JAVA_HOME 路径:$JAVA_HOME,得到 /usr/local/java/jdk1.7.0 ...

  9. HDU 6127 Hard challenge(扫描线)

    http://acm.hdu.edu.cn/showproblem.php?pid=6127 题意: 有n个点,每个点有一个$(x,y)$坐标和一个权值,任意两点之间都有连线,并且连线的权值为两个顶点 ...

  10. HDU 1686 Oulippo

    http://acm.hdu.edu.cn/showproblem.php?pid=1686 题意:给定一个文本串和给定一个模式串,求文本串中有几个模式串. 思路:直接套用KMP模板. #includ ...