博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
scrapy-redis基础和介绍
阅读量:6827 次
发布时间:2019-06-26

本文共 5565 字,大约阅读时间需要 18 分钟。

一、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(
得意自己取得名字) 传送门:
scrapy多个spider不能共享待爬取队列scrqueue, 即scrapy本身不支持爬虫分布式,解决是把这个scrqueue换成redis数据库(也是指redis队列),从同一个redis-server存放要爬取的request,便能让多个spider去同一个数据库里读取。
 
scrapy中跟“待爬队列”直接相关的就是调度器“ ”,它负责对新的request进行入列操作(加入scrqueue),取出下一个要爬取的request(从scrqueue中取出)等操作。它把待爬队列按照优先级建立了一个字典结构,比如:
{
priority0:队列0
priority1:队列2
priority2:队列2
}
然后根据request中的priority属性,来决定该入哪个队列。而出列时,则按priority较小的优先出列。为了管理这个比较高级的队列字典,Scheduler需要提供一系列的方法。原来的Scheduler已经无法使用(被替换掉了,注意上一个红色字段),所以使用scrapy-redis的 组件。
 
scrapy中用集合实现这个request去重功能,scrapy中把已经发送的request指纹放入到一个集合中,把下一个request的指纹拿到集合中比对,如果该指纹存在于集合中,说明这个request发送过了,如果没有则继续操作。( )这个核心的判重功能是这样实现的:
[plain]   
 
  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组件来实现的。

四、最快的安装和启用

安装:

[plain]   
 
  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 中启用组件们:
[plain]   
 
  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

 

[plain]   
 
  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  

 

运行爬虫
[python]   
 
  1. scrapy runspider myspider.py  
向redis中装入url们
 
[python]   
 
  1. redis-cli lpush myspider:start_urls http://xiaowangzhi.com  

 

你可能感兴趣的文章
C#小技巧系列之一:获取系统有关信息
查看>>
[CTO札记]好部下的3个层次
查看>>
Windows下安装Resin及配置详解与发布应用
查看>>
Mongodb数据库安装及使用
查看>>
08-Windows Server 2012 R2 会话远程桌面-标准部署-使用PowerShell进行部署2-1
查看>>
centos7 systemctl 启动 Redis 失败
查看>>
The Hacker's Guide To Python 单元测试
查看>>
编程王道,唯“慢”不破
查看>>
SQL 必知必会·笔记<13>插入数据
查看>>
Openfire与XMPP协议
查看>>
在.NET下如何实现密码Hash化
查看>>
缩略图不变形
查看>>
【计算机视觉必读干货】图像分类、定位、检测,语义分割和实例分割方法梳理...
查看>>
SSIS Execute SQL Task 用法
查看>>
使用枚举和结构输出日期
查看>>
面试题:单词翻转(代码简洁&效率)
查看>>
使用oledb读写excel出现“操作必须使用一个可更新的查询”的解决办法
查看>>
Windows Azure Cloud Service (11) PaaS之Web Role, Worker Role(上)
查看>>
OEA 中 WPF 树型表格虚拟化设计方案
查看>>
《Android深度探索(卷1):HAL与驱动开发》虚拟实验环境(Ubuntu Linux)免费下载,不需要CPU虚拟化支持...
查看>>