(如下內容所有爲轉載,供本身查閱用)html
下載地址:數據庫
http://code.google.com/p/crawler4j/小程序
Crawler4j的使用windows
網上對於crawler4j這個爬蟲的使用的文章不多,Google到的幾乎沒有,只能本身根據crawler4j的源碼進行修改。這個爬蟲最大的特色就是簡單易用,他連API都不提供。剛開始的時候實在恨不能適應。好在他的源碼也提供了幾個例子。對於通常的應用大能夠直接修改它的例子。多線程
使用方法很簡單,直接用Eclipse打開工程。能夠看到src下有三個demo例子。說一下最簡單的simple例子。函數
使用crawler4j的關鍵的繼承WebCrawler類實現本身的爬蟲類MyCrawler,而後根據須要覆蓋WebCrawler的幾個函數就能夠了。工具
public boolean shouldVisit(WebURL url) // 根據url進行網頁的解析,對返回爲TRUE的網頁進行抓取。fetch
public void visit(Page page) // 解析網頁內容,page類包含了豐富的方法,能夠利用這些方法獲得網頁的內容和屬性。網站
Crawler包
Crawler.CrawController 控制爬蟲,先addseed,再開啓多個爬蟲,並不斷監聽各個爬蟲存活狀態。
Crawler.WebCrawler 爬蟲
1. Run():不斷循環,每次從Frontier拿50條url,對每條url,processPage(curUrl)。
2. processPage(curURL):用PageFetcher.fetch爬取網頁,若是curURL有redirect,則將redirect url的url加入Frontier,之後再調度;若是爬取正常,則先進行parse,生成Page,將新urls降入Frontier(新加入url的深度此時肯定),調用visit(Page){用戶自定義操做}。
Crawler.Configurations 讀取crawler4j.properties中的信息
Crawler.PageFetcher 啓動IdleConnectionMonitorThread,用fetch(Page, ignoreIfBinary),爬取單個Page頁面。是一個static類。
Crawler.Page 一個頁面
Crawler.PageFetchStatus 單個頁面爬取的配置,如返回爬取狀態數字所表明的含義等等。
Crawler.HTMLParser 對HTML源碼進行parse,存入Page中。
Crawler.LinkExtractor 抽取出一個HTML頁面中包含的全部link。
Crawler.IdleConnectionMonitorThread 用來監聽鏈接器(用來發送get請求,獲取頁面),其connMgr則負責HTML請求的發送。
url包
url.WebURL 表明一條url,內含docid, depth, url值
url.URLCanonicalizer 將url進行normalize
Frontier包
Frontier.Frontier
Init() 若是resumable,則從env所指home中讀取已處理過得urls,scheduleAll加入調度workQueue中。
Frontier.workQueues 要處理的頁面集,若是resumable,在構造時會打開對應env中的database(PendingURLsDB),獲取上一次遺留的未處理的urls。
Frontier.inprocessPages 當前正在處理的頁面集,繼承workQueues,存入InProcessPagesDB數據庫。
Frontier.DocIDServer 對應數據庫DocIDs,記錄已經見過的頁面url。
處理流程:newurl--->workQueues--->inprovessPages--->deletegoogle
Robotstxt包,用來判斷url是否被容許。
Util包,用來提供一些小工具。
注意點:
1. seed頁面深度爲0。
2. url去重利用的是DocIDServer.newdocid(url),若是該值大於0,則表示該url之前見過。經過這個機制,全部之前見過的頁面均可以被記錄識別。
3. 當設定resumable後,程序跑完後就會把PendingURLsDB和DocIDs保存下來。
4. 若是不設定resumable,在運行程序前,會把env對應的home目錄清空。
------------------------------------------------------------------------------
因爲最近作實驗須要使用到大量的新聞語料庫,在網上找了一些都不是本身想要的,因此決定本身寫個小程序去爬取New York Times(NYT)上的網頁新聞。
用Java寫的爬蟲程序有不少,我找了一個叫crawler4j的開源爬蟲,這是一個多線程的爬蟲,功能比較簡單,源代碼也比較容易看懂,因爲我要對爬蟲爬取連接進行一些修改,就直接下了crawler4j的源碼加到我本身的工程中。
而後對爬下來的網頁進行處理,使用的是htmlparser這個工具,獲得了我要的新聞的Title、Publication Time、Discription、正文等信息。爲了更好的組織這些信息,我把這些信息存儲到XML文檔中。
花了兩個晚上的時間,爬蟲程序能夠跑起來了,寫程序的時候遇到了幾個問題。
1. 在xml中是使用 "\n" 來表示換行的,而在windows中是使用 "\r\n" 來表示換行符的,因此你要是把含有換行符的文本保存到xml文檔時他會自動的把 "\r" 轉換成轉義符 "& #13;" ,要處理掉這個的話,你能夠直接把文本里的 "\r" 給刪了就好了。
2. 使用Java中的String.replaceAll(regex, replacement)這個函數時又犯了一個很低級的錯誤,就是若是執行str.replaceAll(regex, replacement) 時並無改變str自己的值,因此說要替換str自身的某些字符串時須要執行 str=str.replaceAll(regex, replacement) ,沒有意識的這個問題的後果就是花了很長時間在糾結個人程序哪兒出問題了,已是第二次犯這個錯誤了,之後不能再犯了啊。
3. 爬取國外的網站資源太慢了,程序開了兩個小時左右才爬取了3000篇新聞,慢的可憐啊,但願多開幾個線程看看能不能提高一點效果,要是是因爲網速的緣由的話,可能效果不大。
----------------------------------------------------------------------------
Crawler4j的退出問題
這個問題在網上找了很久也沒有好的解決方案,網上的說法是這個爬蟲只支持手動強制關閉。無奈只能本身看他的源代碼,好在他的源代碼也很少。目前的解決方案是。。。直接上代碼吧
1、edu.uci.ics.crawler4j.crawler.CrawlController類
public CrawlController(String storageFolder) throws Exception {
。。。
// 新建一個監控線程,不知管什麼用
// PageFetcher.startConnectionMonitorThread();
}
public <T extends WebCrawler> void start(Class<T> _c, int numberOfCrawlers) {
。。。
// 設置中止標誌
sign_stop = false;
while (true) {
。。。
}
// 中止線程
if(sign_stop){
for (int i = 0; i < crawlers.size(); i++) {
crawlers.get(i).setStop(true);
}
return;
}
if (!someoneIsWorking) {
。。。
}
public void stop() {
sign_stop = true;
}
2、edu.uci.ics.crawler4j.crawler.WebCrawler類
// 中止標誌
private boolean stop;
public void run() {
onStart();
stop = false;
while (!stop) {
。。。
} }