原來的scrapy中的scheduler維護的是當前機器中的任務佇列(存放著request物件以及**函式等資訊) + 當前的去重佇列(存放訪問過的url位址)
實現分布式的關鍵就是需要找一台專門的主機在上面執行乙個共享的佇列,比如redis。然後重寫scrapy的scheduler,讓新的scheduler到共享的佇列中訪問request,並且去除重複的request請求
1、共享佇列
2、重寫scheduler,讓它不論是去重還是執行任務都去訪問共享佇列中的內容
3、為scheduler專門定製去重規則(利用redis的集合型別)
在scrapy中使用redis的共享去重佇列
#1、在settings中配置redis鏈結
redis_host='
localhost'#
主機名稱
redis_port='
6379'#
埠號redis_url='
redis://user:pass@hostname:9001'#
連線url,優先於上面的配置
redis_params={} #
redis連線引數
redis_params['
redis_cls
'] = '
myproject.redisclient'#
指定連線redis的python模組
redis_encoding = '
utf-8'#
redis的編碼型別
#2、讓scrapy使用共享的去重佇列
#使用scrapy_redis提供的去重功能,其實是利用redis的集合來實現的
dupefilter_class = '
scrapy_redis.dupefilter.rfpdupefilter'#
3、需要指定redis中集合的key名稱,key=存放不重複request字串的集合
dupefilter_key = '
dupefilter:%(timestamp)s
'
#資料的持久化scrapy_redis去重+排程實現分布式採集
#settings中的配置
scheduler = '
scrapy_redis.scheduler.scheduler'#
排程器將不重複的任務用pickle序列化後放入共享的任務佇列中,預設是
使用優先順序佇列(預設),別的還有priorityqueue(有序集合),fifoqueue(列表),lifoqueue(列表)。
scheduler_queue_class = '
scrapy_redis.queue.priorityqueue'#
對儲存到redis中的request物件進行序列化,預設是通過pickle來進行序列化的
scheduler_serializer = '
scrapy_redis.picklecompat'#
排程器中請求任務序列化後存放在redis中的key
scheduler_queue_key = '
%(spider)s:requests'#
是否在關閉時候保留原來的排程器和去重記錄,true=保留,false=清空
scheduler_persist =true
#是否在開始之前清空排程器和去重記錄,true=清空,false=不清空
scheduler_flush_on_start =false
#去排程器中獲取資料的時候,要是是空的話最多等待的時間(最後沒資料、未獲取到資料)。如果沒有的話就立刻返回會造成空迴圈次數過多,cpu的占有率會直線飆公升
scheduler_idle_before_close = 10
#去重規則,在redis中儲存的時候相對應的key
scheduler_dupefilter_key = '
%(spider)s:dupefilter'#
去重規則對應處理的類,將任務request_fingerprint(request)得到的字串放到去重佇列中
scheduler_dupefilter_class = '
scrapy_redis.dupefilter.repdupefilter
'
#當從目標站點解析出我們想要的內容以後儲存成item物件,就會由引擎交給pipeline來進行資料持久化操作/儲存到指定的資料庫中,scrapy_redis提供了乙個pipeline元件,可以幫助我們將item儲存到redis中
#將item持久化儲存到redis的時候,指定key和序列化函式
redis_items_key = '
%(spider)s:items
'redis_items_serializer = '
json.dumps
'
#從redis中獲取起始的url
scrapy程式爬蟲目標站點,一旦爬取完成以後就結束了,萬一目標站點內容更新了,拿著時候我們要是還想在此採集的話,就需要重新啟動這個scrapy專案,這就會變的非常麻煩,scrapy_redis提供了一種讓scrapy專案從redis中獲取起始的url,如果沒有scrapy就會過一段時間再來取而不會直接結束,所以我們只想要寫乙個簡單的程式指令碼,定期的往redis佇列中放入乙個起始的url就可以了
#編寫指令碼的時候,設定起始url從redis中的key進行獲取
redis_start_urls_key = '
%(name)s:start_urls'#
獲取起始url的時候,去集合中獲取呢還是去列表中獲取:true=集合, false=列表
redis_start_urls_as_set = false #
獲取起始url的時候,要是為true的話,就會使用self.server.spop;false的話就是self.server.lpop
爬蟲 分布式爬蟲
爬蟲的本質 很多搞爬蟲的總愛吹噓分布式爬蟲,彷彿只有分布式才有逼格,不是分布式簡直不配叫爬蟲,這是一種很膚淺的思想。分布式只是提高爬蟲功能和效率的乙個環節而已,它從來不是爬蟲的本質東西。爬蟲的本質是網路請求和資料處理,如何穩定地訪問網頁拿到資料,如何精準地提取出高質量的資料才是核心問題。分布式爬蟲只...
分布式爬蟲
乙個基於scrapy redis的分布式爬蟲模板,在scrapy redis自帶的example的基礎上進行修改,新增在實際爬取過程中大部分爬蟲可能用到的功能,使的構建分布式爬蟲更加的簡單。scrapy redis windows ubuntu sudo apt get install redis ...
分布式爬蟲
修改普通爬蟲專案為分布式爬蟲 1.主爬蟲檔案myspider.py 做如下修改,其他不做修改 import scrapy from items import myitem 匯入資料模型 from scrapy redis.spiders import redisspider 匯入scrapy red...