原始碼:git clone
一、爬蟲佇列: fifoqueue lifoqueue priorityqueue
class base(object):
"""per-spider base queue class"""
def __init__(self, server, spider, key, serializer=none):
if serializer is none:
serializer = picklecompat
if not hasattr(serializer, 'loads'):
raise typeerror("serializer does not implement 'loads' function: % r"
% serializer)
if not hasattr(serializer, 'dumps'):
raise typeerror("serializer '% s' does not implement 'dumps' function: % r"
% serializer)
self.server = server
self.spider = spider
self.key = key %
self.serializer = serializer
def _encode_request(self, request):
obj = request_to_dict(request, self.spider)
return self.serializer.dumps(obj)
def _decode_request(self, encoded_request):
obj = self.serializer.loads(encoded_request)
return request_from_dict(obj, self.spider)
def __len__(self):
"""return the length of the queue"""
raise notimplementederror
def push(self, request):
"""push a request"""
raise notimplementederror
def pop(self, timeout=0):
"""pop a request"""
raise notimplementederror
def clear(self):
"""clear queue/stack"""
self.server.delete(self.key)
_encode_request() 和 _decode_request() 方法 對request物件進行序列化和反序列化
實現三種佇列方法:定義子類繼承父類base 並重寫_len() _pop() _push
二、去重過濾
原始碼檔案是 dupefilter.py
步驟: 利用redis集合 指紋 server 物件的 sadd() 。獲取指紋之後就直接向集合新增指紋,如果新增成功,說明這個指紋原本不存在於集合中,返回值 1。**中最後的返回結果是判定新增結果是否為 0,如果剛才的返回值為 1,那這個判定結果就是 false,也就是不重複,否則判定為重複。
三、排程器
原始檔名稱是 scheduler.py
scrapy-redis 還幫我們實現了配合 queue、dupefilter 使用的排程器 scheduler,原始檔名稱是 scheduler.py。我們可以指定一些配置,如 scheduler_flush_on_start 即是否在爬取開始的時候清空爬取佇列,scheduler_persist 即是否在爬取結束後保持爬取佇列不清除。我們可以在 settings.py 裡自由配置,而此排程器很好地實現了對接
def enqueue_request(self, request):
if not request.dont_filter and self.df.request_seen(request):
self.df.log(request, self.spider)
return false
if self.stats:
self.stats.inc_value('scheduler/enqueued/redis', spider=self.spider)
self.queue.push(request)
return true
def next_request(self):
block_pop_timeout = self.idle_before_close
request = self.queue.pop(block_pop_timeout)
if request and self.stats:
self.stats.inc_value('scheduler/dequeued/redis', spider=self.spider)
return request
enqueue_request() 可以向佇列中新增 request,核心操作就是呼叫 queue 的 push() 操作,還有一些統計和日誌操作。next_request() 就是從佇列中取 request,核心操作就是呼叫 queue 的 pop() 操作,此時如果佇列中還有 request,則 request 會直接取出來,爬取繼續,否則如果隊列為空,爬取則會重新開始 爬蟲基礎 Scrapy Redis分布式爬蟲元件
scrapy是乙個框架,他本身是不支援分布式的。如果我們想要做分布式的爬蟲,就需要借助乙個元件叫做scrapy redis,這個元件正是利用了redis可以分布式的功能,整合到scrapy框架中,使得爬蟲可以進行分布式。可以充分的利用資源 多個ip 更多頻寬 同步爬取 來提高爬蟲的爬行效率。可以充分...
scrapy redis分布式爬蟲
依賴環境 scrapy 1.1 redis 2.8 分布式爬蟲 將乙個專案拷貝到多台電腦上,同時爬取資料。1.必須保證所有電腦上的 是相同的配置。2.在其中一台電腦上啟動redis和mysql的資料庫服務。3.同時將所有的爬蟲專案執行起來。4.在啟動redis和mysql資料庫的電腦上,向redis...
94 爬蟲 scrapy redis實戰(五)
有緣網的資料爬回來了,但是放在redis裡沒有處理。之前我們配置檔案裡面沒有定製自己的item pipelines,而是使用了redispipeline,所以現在這些資料都被儲存在redis的youyuan items鍵中,所以我們需要另外做處理。在scrapy youyuan目錄下可以看到乙個pr...