負責執行requst的去重,實現的很有技巧性,使用的redis的設定資料結構。但是注意排程並不使用其中用於在這個模組中實現的dupefilter鍵做請求的排程,而是使用queue.py模組中實現的佇列。
當請求不重複時,將其存入到佇列中,排程時將其彈出。
這個檔案看起來比較複雜,重寫了scrapy本身已經實現的請求判重功能。因為本身scrapy單機跑的話,只需要讀取記憶體中的請求佇列或者持久化的請求佇列(scrapy預設的持久化似乎是json格式的檔案,不是資料庫)就能判斷這次要發出的請求url是否已經請求過或者正在排程(本地讀就行了)。而分布式跑的話,就需要各個主機上的scheduler都連線同乙個資料庫的同乙個請求池來判斷這次的請求是否是重複的了。
在這個檔案中,通過繼承basedupefilter重寫他的方法,實現了基於redis的的判重。根據源**來看,scrapy,redis的使用了scrapy本身的乙個指紋接request_fingerprint,這個介面很有趣,根據scrapy文件所說,他通過雜湊來判斷兩個**是否相同(相同的url會生成相同的雜湊結果),但是當兩個**的位址相同,得到型引數相同但是順序不同時,也會生成相同的雜湊結果(這個真的比較神奇......)所以scrapy-redis的依舊使用url的指紋來判斷請求請求是否已經出現過。
這個類通過連線redis的,使用乙個金鑰來向redis的的乙個設定中插入指紋(這個金鑰對於同一種蜘蛛是相同的,redis的是乙個鍵 - 值的資料庫,如果金鑰是相同的,訪問到的值就是相同的,這裡使用蜘蛛名字+ dupefilter的關鍵就是為了在不同主機上的不同爬蟲例項,只要屬於同一種蜘蛛,就會訪問到同乙個組,而這個組就是他們的**判重池),如果返回值為0,說明該設定中該指紋已經存在(因為集合是沒有重複值的),則返回假,如果返回值為1,說明新增了乙個指紋到集合中,則說明這個請求沒有重複,於是返回真,還順便把新指紋加入到資料庫中了。dupefilter判重在排程類中用,每乙個請求在進入排程之前都要進行判重,如果重複就不需要參加排程,直接捨棄就好了,不然就是白白浪費資源。
erlang原始碼參考
1 資料型別的記憶體 2 siyao同學一系列介紹資料型別實現的文章 erlang資料型別的表示和實現 1 資料型別回顧 erlang資料型別的表示和實現 2 eterm 和立即數 erlang資料型別的表示和實現 3 列表 erlang資料型別的表示和實現 4 boxed 物件 erlang資料型...
Spring原始碼學習參考
spring源 解析 一 ioc容器 spring源 解析 二 ioc容器在web容器中的啟動 spring源 解析 三 spring jdbc spring源 解析 四 spring mvc spring源 解析 五 spring aop獲取proxy spring源 解析 六 spring宣告式...
spring原始碼分析 spring原始碼分析
1.spring 執行原理 spring 啟動時讀取應用程式提供的 bean 配置資訊,並在 spring 容器中生成乙份相應的 bean 配置登錄檔,然後根據這張登錄檔例項化 bean,裝配好 bean 之間的依賴關係,為上 層應用提供準備就緒的執行環境。二 spring 原始碼分析 1.1spr...