爬蟲URL去重

這個要看你想抓取的網頁數量是哪一種規模的。
若是是千萬如下用hash表, set, 布隆過濾器基本能夠解決,若是是海量的。。。。。。嗯我也沒作過海量的,不過hash表之類的就別想了,內存根本不夠,分割線下面是個人一個想法,歡迎你們討論。
布隆過濾器,大概幾十行代碼就能夠實現。能夠節省不少內存(我本身寫了一個沒有太多優化,佔用內存大概是hash存儲的1/4甚至更小)。
-------------------分割--------------------html

http://www.xxx.com/path/filename.html
 ------|---host----|---filename------|
假設網絡上有一億個page,對應了一億個url, 因爲資源限制我不能直接存儲全部的url,甚至hash以後存儲都存不下,可是我能夠發現,網絡上總共只有1萬個網站,平均每一個網站有1萬個page,換個方式。我只要維護兩個hash表,一個用來記錄我全部抓取過的host,一個用來記錄正在抓取的網站的filename,這樣只要兩個hash表就能夠對1億個url去重了。而後你須要一個數據庫,抓取到一個網頁以後判斷裏面的連接,指向當前網站就繼續抓,不然,這條url存到數據庫裏面,當前網站抓取結束,繼續處理下一個網站。。。。
 
 

在爬蟲中,會記錄下已爬過的URL,而後每次有新的URL會和這個集合比較,看看是否存在。在集合很大的時候,存儲這些URL會須要很大的存儲空間,並且比對時遍歷過去,須要必定時間。算法

針對這個問題,能夠採用布隆過濾器,左程雲在他的算法數據結構最優解一書中有講到,我這裏簡單描述一下。數據庫


選取一個m長的bit數組,數組每一位佔一個bit,即0或者1,再選擇k個哈希函數,每一個函數都能把url分散的映射到1~m的一個值上,將這個值對應到剛剛的數組裏面,把對應位置置爲1,每一個URL通過個hash映射,在比較理想狀況下,數組上會有k個位置設爲1。以後沒添加進來一個URL,到將其對應的k個位置設爲1,這樣隨着加進來的url數量增多,數組上會有愈來愈多的1,固然還會有0。數組

比對時,將新的URL映射一下,比對這映射的k個位置是否都爲1,不都爲1則表示這個url以前沒有遇到過,不然就是遇到過。網絡


這個算法裏面會存在一下偏差,可是肯定好m和k的數量後,準確率很高,並且減小了存儲空間,結果仍是比較優秀的,具體m,k及失誤率的推導計算這裏不細講了,見左程雲的講解。
 
 

看看scrapy 文檔的Duplicates filter這一章吧。數據結構

簡單的方法,就是哈希一下url,把哈希值存到一個set() 裏面,抓以前哈希url以後,去判斷一下set裏面有沒有有着url值。
相關文章
相關標籤/搜索