scrapy-redis可重点参考

http://blog.csdn.net/u013378306/article/details/54017933

 

scrapy-redis安装及配置

scrapy-redis 的安装

pip install scrapy-Redis

easy_install scrapy-redis

下载

http://redis.io/download

版本推荐

stable 3.0.2

运行redis

redis-server redis.conf

清空缓存

redis-cli flushdb

scrapy配置redis

settings.py配置redis(在scrapy-redis 自带的例子中已经配置好)

SCHEDULER = "scrapy_redis.scheduler.Scheduler"

SCHEDULER_PERSIST = True

SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderPriorityQueue'

REDIS_URL = None # 一般情况可以省去

REDIS_HOST = '127.0.0.1' # 也可以根据情况改成 localhost

REDIS_PORT = 6379

在scrapy中使用scrapy-redis

spider 继承RedisSpider

class tempSpider(RedisSpider)  

name = "temp"

redis_key  = ''temp:start_url"

启动redis

在redis的src目录下,执行 ./redis-server启动服务器

执行 ./redis-cli 启动客户端


设置好setting.py的redis 的ip和端口

启动scropy-redis的代码;

如启动name= "lhy",start_urls="lhy:start_urls" 的spider。

如果在redis中没有 主键为lhy:start_urls 的list,则爬虫已只监听等待。

此时,在redis客户端执行:lpush lhy:start_urls   http://blog.csdn.NET/u013378306/article/details/53888173

可以看到爬虫开始抓取。在 redis客户端下输入 keys *,查看所有主键

原来的 lhy:start_urls 已经被自动删除,并新建了 一个lhy:dupefilter (set),一个 lhy:items (list), 一个 lhy:requests(zset) 

lhy:dupefilter用来存储 已经requests 过的url的hash值,分布式去重时使用到,  lhy:items是分布式生成的items,lhy:requests是新生成的 url封装后的requests。

理论上,lhy:dupefilter 等于已经request的数量,一直增加

lhy:items 是经过 spider prase生成的

lhy:requests 是有序集合ZSET,scrapy-redis 重新吧他封装成了一个队列,requests是spider 解析生成新url后重新封装,如果不载有新的url产生,则随着spider的prase,一直减少。总之取request时出队列,新的url会重新封装成request后增加进来,入队列。

scrapy-redis 原理及解释

scrapy-redis 重写了scrapy的多个类,具体请看http://blog.csdn.Net/u013378306/article/details/53992707

并且在setting.py中 配置了这些类,所以当运行scrapy-redis例子时,自动使用了scrapy-redis 重写的类。


下载scrapy-redis源代码 https://github.com/rolando/scrapy-Redis

文档结构如下:

其中,src 中是scrapy-redis的源代码。

example-redis 是写好的例子,其中有三个例子

(1)domz.py   (2) mycrawler_redis.py   (3) myspider.py

文档中队者三个例子的解释如下

[python] view plain copy
  1. * **dmoz**  
  2.   
  3.   This spider simply scrapes dmoz.org.  
  4.   
  5. * **myspider_redis**  
  6.   
  7.   This spider uses redis as a shared requests queue and uses  
  8.   ``myspider:start_urls`` as start URLs seed. For each URL, the spider outputs  
  9.   one item.  
  10.   
  11. * **mycrawler_redis**  
  12.   
  13.   This spider uses redis as a shared requests queue and uses  
  14.   ``mycrawler:start_urls`` as start URLs seed. For each URL, the spider follows  
  15.   are links.  


domz.py :此例子仅仅是抓取一个网站下的数据,没有用分布式

[python] view plain copy 在CODE上查看代码片派生到我的代码片
  1. from scrapy.linkextractors import LinkExtractor  
  2. from scrapy.spiders import CrawlSpider, Rule  
  3.   
  4.   
  5. class DmozSpider(CrawlSpider):  
  6.     """Follow categories and extract links."""  
  7.     name = 'dmoz'  
  8.     allowed_domains = ['dmoz.org']  
  9.     start_urls = ['http://www.dmoz.org/']  
  10.   
  11.     rules = [  
  12.         Rule(LinkExtractor(  
  13.             restrict_css=('.top-cat', '.sub-cat', '.cat-item')  
  14.         ), callback='parse_directory', follow=True),  
  15.     ]  
  16.   
  17.     def parse_directory(self, response):  
  18.         for div in response.css('.title-and-desc'):  
  19.             yield {  
  20.                 'name': div.css('.site-title::text').extract_first(),  
  21.                 'description': div.css('.site-descr::text').extract_first().strip(),  
  22.                 'link': div.css('a::attr(href)').extract_first(),  
  23.             }  

mycrawler_redis.py
此例子 使用 RedisCrawlSpider类,支持分布式去重爬取,并且 可以定义抓取连接的rules

[python] view plain copy 在CODE上查看代码片派生到我的代码片
  1. from scrapy.spiders import Rule  
  2. from scrapy.linkextractors import LinkExtractor  
  3.   
  4. from scrapy_redis.spiders import RedisCrawlSpider  
  5.   
  6.   
  7. class MyCrawler(RedisCrawlSpider):  
  8.     """Spider that reads urls from redis queue (myspider:start_urls)."""  
  9.     name = 'mycrawler_redis'  
  10.     redis_key = 'mycrawler:start_urls'  
  11.   
  12.     rules = (  
  13.         # follow all links  
  14.         Rule(LinkExtractor(), callback='parse_page', follow=True),  
  15.     )  
  16.   
  17.     def __init__(self, *args, **kwargs):  
  18.         # Dynamically define the allowed domains list.  
  19.         domain = kwargs.pop('domain', '')  
  20.         self.allowed_domains = filter(None, domain.split(','))  
  21.         super(MyCrawler, self).__init__(*args, **kwargs)  
  22.   
  23.     def parse_page(self, response):  
  24.         return {  
  25.             'name': response.css('title::text').extract_first(),  
  26.             'url': response.url,  
  27.         }  


myspider.py 此例子支持分布式去重爬取,但不支持定义规则抓取url

[python] view plain copy 在CODE上查看代码片派生到我的代码片
  1. from scrapy_redis.spiders import RedisSpider  
  2.   
  3.   
  4. class MySpider(RedisSpider):  
  5.     """Spider that reads urls from redis queue (myspider:start_urls)."""  
  6.     name = 'myspider_redis'  
  7.     redis_key = 'myspider:start_urls'  
  8.   
  9.     def __init__(self, *args, **kwargs):  
  10.         # Dynamically define the allowed domains list.  
  11.         domain = kwargs.pop('domain', '')  
  12.         self.allowed_domains = filter(None, domain.split(','))  
  13.         super(MySpider, self).__init__(*args, **kwargs)  
  14.   
  15.     def parse(self, response):  
  16.         return {  
  17.             'name': response.css('title::text').extract_first(),  
  18.             'url': response.url,  
  19.         }  


posted @ 2017-04-26 16:12  猪啊美  阅读(54)  评论(0)    收藏  举报