WebMagic是一個簡單靈活的Java爬蟲框架。基於WebMagic,你能夠快速開發出一個高效、易維護的爬蟲。html
最新版:WebMagic-0.7.3java
<dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-core</artifactId> <version>0.7.3</version> </dependency> <dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-extension</artifactId> <version>0.7.3</version> </dependency>
上邊是簡單的介紹,相關使用參考做者編寫的 中文文檔git
下面是使用的相關拓展部分:github
Scheduler
是WebMagic
中進行 URL 管理的組件。通常來講,Scheduler
包括兩個做用:web
Scheduler的內部實現進行了重構,去重部分被單獨抽象成了一個接口:DuplicateRemover
,從而能夠爲同一個Scheduler選擇不一樣的去重方式,以適應不一樣的須要,目前提供了三種去重方式。redis
布隆過濾器的使用實例:算法
@Scheduled(initialDelay = 1000, fixedDelay = 60 * 1000 * 60 * 12) public void start() { Spider.create(new BdProcessor()) .addUrl(URL) .thread(10) // 設置布隆過濾器去重操做(默認使用HashSet來進行去重,佔用內存較大;使用BloomFilter來進行去重,佔用內存較小,可是可能漏抓頁面) .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000000))) .addPipeline(dbPipeline) .run(); }
最多見的去重方案是生成文檔的指紋門。例如對一篇文章進行 MD5 加密生成一個字符串,咱們能夠認爲這是文章的指紋碼,再和其餘的文章指紋碼對比,一致則說明文章重複。api
可是這種方式是徹底一致則是重複的,若是文章只是多了幾個標點符號,那仍舊被認爲是重複的,這種方式並不合理。服務器
這種方式就是咱們以前對 url 進行去重的方式,使用在這裏的話,也是對文章進行計算獲得一個數,再進行對比,缺點和方法 1 是同樣的,若是隻有一點點不同,也會認爲不重複,這種方式不合理。網絡
KMP 算法是一種改進的字符串匹配算法。KMP 算法的關鍵是利用匹配失敗後的信息,儘可能減小模式串與主串的匹配次數以達到快速匹配的目的。可以找到兩個文章有哪些是一-樣的,哪些不同。。
這種方式可以解決前面兩個方式的「只要一點不同就是不重複」的問題。可是它的時空複雜度過高了,不適合大數據量的重複比對。
Google 的 simhash 算法產生的簽名,能夠知足上述要求。這個算法並不深奧,比較容易理解。這種算法也是目前 Google 搜索引擎所目前所使用的網頁去重算法。
有些網站不容許爬蟲進行數據爬取,由於會加大服務器的壓力。其中一種最有效的方式是經過 ip+時間進行鑑別,由於正常人不可能短期開啓太多的頁面,發起太多的請求。
咱們使用的 WebMagic 能夠很方便的設置爬取數據的時間(參考次日的的 3.1. 爬蟲的配置、啓動和終止)。可是這樣會大大下降咱們 J 爬取數據的效率,若是不當心 ip 被禁了,會讓咱們沒法爬去數據,那麼咱們就有必要使用代理服務器來爬取數據。
代理 L(英語:Proxy),也稱網絡代理,是一-種特殊的網絡服務,容許一個網絡終端(通常爲客戶端)經過這個服務與另外一個網絡終端(通常爲服務器)進行非直接的鏈接。
提供代理服務的電腦系統或其它類型的網絡終端稱爲代理服務器(英文:Proxy. Server)。一個完整的代理請求過程爲:客戶端首先與代理服務器建立鏈接,接着根據代理服務器所使用的代理協議,請求對目標服務器建立鏈接、或者得到目標服務器的指定資源。
咱們就須要知道代理服務器在哪裏(ip 和端口號)纔可使用。網上有不少代理服務器的提供商,可是大可能是免費的很差用,付費的還行。推薦個免費的服務網站:
WebMagic的代理API ProxyProvider
。由於相對於 Site 的「配置」,ProxyProvider定位更可能是一個「組件」,因此代理再也不從Site設置,而是由HttpClientDownloader
設置。
HttpClientDownloader.setProxyProvider(ProxyProvider proxyProvider)
ProxyProvider
有一個默認實現:SimpleProxyProvider
。它是一個基於簡單Round-Robin的、沒有失敗檢查的ProxyProvider。能夠配置任意個候選代理,每次會按順序挑選一個代理使用。它適合用在本身搭建的比較穩定的代理的場景。
代理示例:
設置單一的普通HTTP代理爲101.101.101.101的8888端口,並設置密碼爲"username","password"
HttpClientDownloader httpClientDownloader = new HttpClientDownloader(); httpClientDownloader.setProxyProvider(SimpleProxyProvider.from(new Proxy("101.101.101.101",8888,"username","password"))); spider.setDownloader(httpClientDownloader);
設置代理池,其中包括101.101.101.101和102.102.102.102兩個IP,沒有密碼
HttpClientDownloader httpClientDownloader = new HttpClientDownloader(); httpClientDownloader.setProxyProvider(SimpleProxyProvider.from( new Proxy("101.101.101.101",8888) ,new Proxy("102.102.102.102",8888)));