一、問題緣由
(一)去重
筆者最近正在做一個爬取小說網站的後臺端,遇到一個問題:有些URL重複爬取了。儘管重複爬取的頁面不多,但是還是對程序造成了一些困擾,所以嘗試去找到一種可以百分百去重的手段。
通過查閱相關資料,知道 Webmagic 去重靠的是Scheduler
,默認使用的是QueueScheduler
,同時在資料中還看到了 RedisScheduler
。我們都知道,Redis 具有天然的單線程特性,不需要使用額外的同步方法,都能保證同一時間僅有一個線程可以訪問 Redis,同時查閱 RedisScheduler
源碼可知,採用的是 Redis 的 set 進行去重,這樣更加保證了一個 Url 只會被爬取一次(PS:因爲所有待爬取的 Url 先被放入 Redis 中,然後再被 Spider 取出來進行爬取操作的,而 Redis Set 中就保證了不會出現重複的Url)。
(二)增量
因爲小說網站是不斷更新的,我需要知道每天新增了哪些小說,更新了哪些章節。但是由於小說很多,章節更是龐大,若是每天來一個全量爬取,沒有意義,畢竟新增的小說是少數,大部分還是原有的。所以,就涉及到第二個問題,怎樣保證前一天怕取過的小說,今天不再被爬取,只爬取最新更新的。所以就涉及到第二個問題:增量爬取。
二、解決辦法
(一)去重
解決辦法也相對簡單,在虛擬機中啓動 redis-server
,然後在 spider 中設置 RedisScheduler
,具體代碼參見如下:
spider = Spider.create(new NovelProcessor())
.addUrl(NOVEL_WEBSITE_URL)
.addPipeline(new NovelPipeline())
.setDownloader(new HttpClientDownloader())
.setScheduler(new RedisScheduler("192.168.10.130"))
.thread(10);
備註:關於這裏爲什麼沒有設置端口:這是因爲 Webmagic 默認提供了的 Redis 端口爲6379,若讀者不是這個端口,則需要自己單獨設置。
(二)增量
增量的解決思路也是類似,因爲redis中記錄了已經爬取過的Url,再爬去的時候,會自動將已經爬取過的Url去掉,只爬取新更新的Url。