scrapy-redis(一)


安裝scrapy-redis

pip install scrapy-redis

從GitHub 上拷貝源碼:

clone github scrapy-redis源碼文件     git clone https://github.com/rolando/scrapy-redis.git

 

scrapy-redis的工作流程

 

Scrapy_redis之domz  例子分析

1.domz爬蟲:

 2.配置中:

 

 3.執行domz的爬蟲,會發現redis中多了一下三個鍵

redispipeline中僅僅實現了item數據存儲到redis的過程,我們可以新建一個pipeline(或者修改默認的ExamplePipeline),可以讓數據存儲到任意地方。

 scrapy-redis 的源碼分析

1.Scrapy_redis之RedisPipeline

 

2.Scrapy_redis之RFPDupeFilter

 

 3.Scrapy_redis之Scheduler

 

 

domz相比於之前的spider多了持久化request去重的功能,setting中的配置都是可以自己設定的,

意味着我們的可以重寫去重和調度器的方法,包括是否要把數據存儲到redis(pipeline)

 

1.Scrapy_redis之RedisSpider

 

2. Scrapy_redis之RedisCrawlSpider

 

scrapy-redis 配置:

在爬蟲項目的settings.py文件中,可以做一下配置

# ####################### redis配置文件 #######################
REDIS_HOST = '192.168.11.81'                            # 主機名
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'

# df
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"   # 也可以自定義自己的去重規則

from scrapy_redis.scheduler import Scheduler
SCHEDULER = "scrapy_redis.scheduler.Scheduler"   #  調度器    

from scrapy_redis.queue import PriorityQueue
from scrapy_redis import picklecompat
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'  # 去重規則對應處理的類


from scrapy_redis.pipelines import RedisPipeline

ITEM_PIPELINES = {
   'scrapy_redis.pipelines.RedisPipeline': 300,
}
REDIS_ITEMS_KEY = '%(spider)s:items'
REDIS_ITEMS_SERIALIZER = 'json.dumps'

 

 

Crontab爬蟲定時執行

 

 

 

 Scrapy-redis 中的知識總結

request對象什么時候入隊

  • dont_filter = True ,構造請求的時候,把dont_filter置為True,該url會被反復抓取(url地址對應的內容會更新的情況)

  • 一個全新的url地址被抓到的時候,構造request請求

  • url地址在start_urls中的時候,會入隊,不管之前是否請求過

    • 構造start_url地址的請求時候,dont_filter = True

  def enqueue_request(self, request):
   if not request.dont_filter and self.df.request_seen(request):
       # dont_filter=False Ture True request指紋已經存在 #不會入隊
       # dont_filter=False Ture False request指紋已經存在 全新的url #會入隊
       # dont_filter=Ture False #會入隊
       self.df.log(request, self.spider)
       return False
   self.queue.push(request) #入隊
   return True

scrapy_redis去重方法

  • 使用sha1加密request得到指紋

  • 把指紋存在redis的集合中

  • 下一次新來一個request,同樣的方式生成指紋,判斷指紋是否存在reids的集合中

生成指紋

  fp = hashlib.sha1()
fp.update(to_bytes(request.method))  #請求方法
fp.update(to_bytes(canonicalize_url(request.url))) #url
fp.update(request.body or b'')  #請求體
return fp.hexdigest()

判斷數據是否存在redis的集合中,不存在插入

added = self.server.sadd(self.key, fp)
return added != 0

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM