近日,想寫一個小型的爬蟲框架,可惜的是,zero並沒有寫框架的經驗。因此有必要找一個現有框架來參照下。GOOGLE了下,發現Crawler最適合作為將要寫的框架的參照物。Crawler是一個簡單的爬蟲框架,它實現了爬蟲的共同部分,如URL拼接,網頁編碼等,使得用戶可以專注於提取網頁內容(原文:Crawler is a simple Java web crawler/spider/joe or any other name you want to call it. The main goal is to abstract that boring and error-prone code from your codebase and let you focus on crawling the site. )。閱讀Crawler源碼的過程中,發現有不少值得借鑒的地方,因此將其逐一記錄下來。
1. URL的拼接(UrlUtils.java)
從網頁提取出來的URL(uniform resource locator)有可能是完整的,也有可能是相對的。但是在請求網頁時,只能使用完整的URL。因此要將相對URL變為完整URL。在轉換之前,最好先了解URL的語法:
scheme://domain:port/path?query_string#fragment_id
其中scheme指各種協議,如http, https, ftp等;domain指服務器的域名或者IP;port指端口號;path指文件所在目錄;query_string是服務器上某個程序的輸入數據;fragment_id指頁面的某個位置,其功能是讓用戶打開某個網頁時,自動定位到指定位置上。
根據這個語法,可以得到的拼接步驟如下:
a. 根據各部分的特征(如scheme出現的情況下,一定是出現在最前面),將URL拆為scheme, domain, path, query_string, fragment_id這5個部分
b. 按照scheme, domain, path, query_string, fragment_id的順序檢查URL。如果缺少某部分就將其補上
c. 如果URL中出現"&",則將其全部替換為"&"
d. 將URL編碼為UTF-8,這是為了防止提取的URL含有中文。
2. 網頁源碼的編碼的獲取
網頁源碼的編碼探測一般有兩種方式,一是分析網頁源碼中Meta信息,如contentType,來取得編碼。另一種是使用統計學和啟發式方法對網頁源碼進行探測。由於某些網頁的contentType不包含編碼信息,所以第一種方法不一定行得通,這時就要用第二種方式了。IBM的ICU4J庫就實現了第二種方式,用法如下:
/** * 得到網頁所用編碼 * @param pageContent 網頁的內容 * @return 網頁的編碼方式 */ public static String GetPageCharset(byte[] pageContent){ CharsetDetector detector = new CharsetDetector(); detector.setText(pageContent); CharsetMatch match = detector.detect(); return match.getName(); }
3. 雜項
除了以上兩個主要的方面,還有一些小方面,包括:
a. 使用httpclient前,先將cookie都設置進去
b. 處理網頁前,先檢測mime type是不是想要的
c. 使用org.apache.log4j.Logger記錄運行中的各種信息,以備不時之需
d. 建立一個enum類,將http code的各種狀態進行總結,如OK狀態的code從200到299,redirection的狀態從300到399
e. 當確定不會改變變量的值時,對其使用final關鍵字