WebCollector是一個無須配置、便於二次開發的JAVA爬蟲框架(內核),它提供精簡的的API,只需少量代碼即可實現一個功能強大的爬蟲。WebCollector-Hadoop是WebCollector的Hadoop版本,支持分佈式爬取。
目前WebCollector在Github上維護:https://github.com/CrawlScript/WebCollector
1.WebCollector與傳統網絡爬蟲的區別
傳統的網絡爬蟲傾向於整站下載,目的是將網站內容原樣下載到本地,數據的最小單元是單個網頁或文件。而WebCollector可以通過設置爬取策略進行定向採集,並可以抽取網頁中的結構化信息。
2.WebCollector與HttpClient、Jsoup的區別
WebCollector是爬蟲框架,HttpClient是Http請求組件,Jsoup是網頁解析器(內置了Http請求功能)。
一些程序員在單線程中通過迭代或遞歸的方法調用HttpClient和Jsoup進行數據採集,這樣雖然也可以完成任務,但存在兩個較大的問題:
1) 單線程速度慢,多線程爬蟲的速度遠超單線程爬蟲。
2) 需要自己編寫任務維護機制。這套機制裏面包括了URL去重、斷點爬取(即異常中斷處理)等功能。
WebCollector框架自帶了多線程和URL維護,用戶在編寫爬蟲時無需考慮線程池、URL去重和斷點爬取的問題。
3.WebCollector能夠處理的量級
WebCollector目前有單機版和Hadoop版(WebCollector-Hadoop),單機版能夠處理千萬級別的URL,對於大部分的精數據採集任務,這已經足夠了。WebCollector-Hadoop能夠處理的量級高於單機版,具體數量取決於集羣的規模。
4.WebCollector的遍歷
WebCollector採用一種粗略的廣度遍歷,但這裏的遍歷與網站的拓撲樹結構沒有任何關係,用戶不需要在意遍歷的方式。
網絡爬蟲會在訪問頁面時,從頁面中探索新的URL,繼續爬取。WebCollector爲探索新URL提供了兩種機制,自動解析和手動解析。兩種機制的具體內容請讀後面實例中的代碼註釋。
5.WebCollector 2.x版本新特性
- 1)自定義遍歷策略,可完成更爲複雜的遍歷業務,例如分頁、AJAX
- 2)可以爲每個URL設置附加信息(MetaData),利用附加信息可以完成很多複雜業務,例如深度獲取、錨文本獲取、引用頁面獲取、POST參數傳遞、增量更新等。
- 3)使用插件機制,WebCollector內置兩套插件。
- 4)內置一套基於內存的插件(RamCrawler),不依賴文件系統或數據庫,適合一次性爬取,例如實時爬取搜索引擎。
- 5)內置一套基於Berkeley DB(BreadthCrawler)的插件:適合處理長期和大量級的任務,並具有斷點爬取功能,不會因爲宕機、關閉導致數據丟失。
- 6)集成selenium,可以對javascript生成信息進行抽取
- 7)可輕鬆自定義http請求,並內置多代理隨機切換功能。 可通過定義http請求實現模擬登錄。
- 8)使用slf4j作爲日誌門面,可對接多種日誌
- 9)新增了WebCollector-Hadoop,支持分佈式爬取
6.WebCollector爬取新聞網站實例
import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
import org.jsoup.nodes.Document;
/**
* Crawling news from hfut news
*
* @author hu
*/
public class NewsCrawler extends BreadthCrawler {
/**
* @param crawlPath crawlPath is the path of the directory which maintains
* information of this crawler
* @param autoParse if autoParse is true,BreadthCrawler will auto extract
* links which match regex rules from pag
*/
public NewsCrawler(String crawlPath, boolean autoParse) {
super(crawlPath, autoParse);
/*種子頁面*/
this.addSeed("http://news.hfut.edu.cn/list-1-1.html");
/*正則規則設置*/
/*爬取符合 http://news.hfut.edu.cn/show-xxxxxxhtml的URL*/
this.addRegex("http://news.hfut.edu.cn/show-.*html");
/*不要爬取 jpg|png|gif*/
this.addRegex("-.*\\.(jpg|png|gif).*");
/*不要爬取包含 # 的URL*/
this.addRegex("-.*#.*");
}
@Override
public void visit(Page page, CrawlDatums next) {
String url = page.getUrl();
/*判斷是否爲新聞頁,通過正則可以輕鬆判斷*/
if (page.matchUrl("http://news.hfut.edu.cn/show-.*html")) {
/*we use jsoup to parse page*/
Document doc = page.getDoc();
/*extract title and content of news by css selector*/
String title = page.select("div[id=Article]>h2").first().text();
String content = page.select("div#artibody", 0).text();
System.out.println("URL:\n" + url);
System.out.println("title:\n" + title);
System.out.println("content:\n" + content);
/*如果你想添加新的爬取任務,可以向next中添加爬取任務,
這就是上文中提到的手動解析*/
/*WebCollector會自動去掉重複的任務(通過任務的key,默認是URL),
因此在編寫爬蟲時不需要考慮去重問題,加入重複的URL不會導致重複爬取*/
/*如果autoParse是true(構造函數的第二個參數),爬蟲會自動抽取網頁中符合正則規則的URL,
作爲後續任務,當然,爬蟲會去掉重複的URL,不會爬取歷史中爬取過的URL。
autoParse爲true即開啓自動解析機制*/
//next.add("http://xxxxxx.com");
}
}
public static void main(String[] args) throws Exception {
NewsCrawler crawler = new NewsCrawler("crawl", true);
/*線程數*/
crawler.setThreads(50);
/*設置每次迭代中爬取數量的上限*/
crawler.setTopN(5000);
/*設置是否爲斷點爬取,如果設置爲false,任務啓動前會清空歷史數據。
如果設置爲true,會在已有crawlPath(構造函數的第一個參數)的基礎上繼
續爬取。對於耗時較長的任務,很可能需要中途中斷爬蟲,也有可能遇到
死機、斷電等異常情況,使用斷點爬取模式,可以保證爬蟲不受這些因素
的影響,爬蟲可以在人爲中斷、死機、斷電等情況出現後,繼續以前的任務
進行爬取。斷點爬取默認爲false*/
//crawler.setResumable(true);
/*開始深度爲4的爬取,這裏深度和網站的拓撲結構沒有任何關係
可以將深度理解爲迭代次數,往往迭代次數越多,爬取的數據越多*/
crawler.start(4);
}
}