爬蟲爬取時,需要約束爬取的范圍。基本所有的爬蟲都是通過正則表達式來完成這個約束。
最簡單的,正則:
通過這個正則可以約束爬蟲的爬取范圍,但是這個正則并不是表示爬取新華網所有的網頁。新華網并不是只有www.xinhuanet.com這一個域名,還有很多子域名,類似:news.xinhuanet.com
這個時候我們需要定義這樣一個正則:
http://([a-z0-9]*.)*xinhuanet.com/這樣就可以限制爬取新華網所有的網頁了。
每種爬蟲的正則約束系統都有一些區別,這里拿Nutch、WebCollector兩家爬蟲的正則系統做對比:
Nutch官網:http://nutch.apache.org/
WebCollector官網:http://crawlscript.github.io/WebCollector/
nutch的正則約束是依賴一個配置文件 conf/regex-urlfilter.txt 來實現的。例如:
nutch的正則約束原則是:
1)逐行掃描,對每一行進行如下操作:
去掉正則前面的加號或減號,獲取正則式。看待爬取網頁的url中是否包含當前正則的模式。如果包含,看正則前的符合。如果為+,則當前url無需過濾,返回當前url,如果為-,則當前url需要過濾,返回null。如果待爬取網頁url中不包含當前正則的模式,則跳過(繼續下一行操作)。
2)如果掃描到文件結尾,都沒有返回:
返回null。
有2個地方需要注意:
1)nutch的正則過濾時,采用的匹配函數式Patterm.matcher,而不是Patterm.matches。
Patterm.mather在匹配時,只要找到待爬取網頁的url的子串和正則匹配,就通過。
Patterm.matcher要求待爬取網頁的url和regex完全匹配。例如:
待爬取網頁的網址是 http://www.xinhuanet.com/index.html
正則是^http://([a-z0-9]*.)*xinhuanet.com
這個正則用Patterm.matcher和網頁url可以匹配。因為網頁url的字串http://www.xinhuanet.com和正則能匹配。
但是用Patterm.matches就不能匹配。正則需要改成^http://([a-z0-9]*.)*xinhuanet.com.*才可以和網頁的URL匹配。
也就是說nutch的正則其實是和找url中是否有字串符合正則。所以做nutch的正則配置文件時,要在http前加入^符號,如果正則沒有加^符號,例如+http://www.xinhuanet.com ,下面網址也是可以匹配的:
http://www.abc.com/index.php?name=http://www.xinhuanet.com
2)nutch正則過濾時,是逐行掃描,一旦掃描到匹配行就返回結果。所以正則式的順序很重要。例如可以通過下面的配置文件來完成全網爬取(需要過濾圖片等文件為不爬取):
如果當前url不對應gif、JPG等文件,會繼續掃描第二行,第二行可以匹配任意字符串。由于前面符號是+,所以返回當前url,當前url被接受。
1.至少符合一條正例正則。
2.不能符合任意一條反例正則。
正例正則以+開頭,反例正則以-開頭(如果前面不加符號,默認是正例正則)。
上面代碼中,http://www.xinhuanet.com/auto/index.html就可以被接受。因為它符合一條正例http://www.xinhuanet.com/.* ,不符合任意一條反例正則(http://www.xinhuanet.com/special/.*和http://www.xinhuanet.com/info/.*)。
必須給出至少一條正例正則,才可以進行爬取,如果沒有正例正則,不能符合上面的條件一。
WebCollector中正則匹配采用的是Patterm.matches,要求正則與URL完全匹配。如果上面代碼中你的正則寫成+http://www.xinhuanet.com/,而不是+http://www.xinhuanet.com/.*,那么只有網頁http://www.xinhuanet.com/可以被接受,網頁http://www.xinhuanet.com/index.html就不能被接收。
下面給出一個例子,爬取新華網的news.xinhuanet.com子域名,過濾掉gif和jpg圖像: