這個要看你想抓取的網頁數量是哪種規模的。
如果是千萬以下用hash表, set, 布隆過濾器基本可以解決,如果是海量的。。。。。。嗯我也沒做過海量的,不過hash表之類的就別想了,內存根本不夠,分割線下面是我的一個想法,歡迎大家討論。
布隆過濾器,大概幾十行代碼就可以實現。可以節省很多內存(我自己寫了一個沒有太多優化,占用內存大概是hash存儲的1/4甚至更小)。
-------------------分割--------------------
http://www.xxx.com/path/filename.html
------|---host----|---filename------|
在爬蟲中,會記錄下已爬過的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值。