爬蟲的自我解剖(抓取網頁HtmlUnit)
網路爬蟲第一個要面臨的問題,就是如何抓取網頁,抓取其實很容易,沒你想的那麼複雜,一個開源HtmlUnit
包,4行程式碼就OK啦,例子如下:
1 2 3 4 |
final WebClient
webClient= new WebClient();
final HtmlPage
page=webClient.getPage( );
System.out.println(page.asText());
webClient.closeAllWindows();
|
在程式中寫上上面的4行程式碼,執行,就可以得到煙雨林部落格首頁的全部內容,上面程式碼在執行的過程中會出現很多警告,出現這些警告的主要原因是由於以下兩點:
1、HtmlUnit
對Javascript
的支援不是很好
2、HtmlUnit
對CSS
的支援不是很好
明白了上面的兩點後,將程式碼重新改寫一下,該禁用的就禁用,同時禁用一些不必要的功能,也有利於提高程式的執行效率,再者說網路爬蟲也不需要CSS的支援滴
1 2 3 4 5 6 |
final WebClient
webClient= new WebClient();
webClient.getOptions().setCssEnabled( false );
webClient.getOptions().setJavaScriptEnabled( false );
final HtmlPage
page=webClient.getPage( );
System.out.println(page.asText());
webClient.closeAllWindows();
|
HtmlUnit
的使用: 簡介:HtmlUnit
說白了就是一個瀏覽器,這個瀏覽器是用Java寫的無介面的瀏覽器,正因為其沒有介面,因此執行的速度還是可以滴,HtmlUnit
提供了一系列的API,這些API可以乾的功能比較多,如表單的填充,表單的提交,模仿點選連結,由於內建了Rhinojs
引擎,因此可以執行Javascript
作用:web的自動化測試(最初的目的),瀏覽器,網路爬蟲
重要API的使用 在介紹API的使用之前要先明白的一個問題是,WebClient,WebWindow,Page三者之間的關係,所有的頁面最終都是在一個WebWindow物件裡面,WebClient在建立時會自動的建立一個WebWindow物件,當呼叫getPage時會將新頁面載入到WebWindow裡,你可以理解成WebClient就是IE核心,WebWindow就是呈現頁面的瀏覽器視窗,三者之間的關係圖如下圖所示:
1、模擬特定瀏覽器,也可以指定瀏覽器的相應版本(HtmlUnit最新版2.13現在可以模擬的瀏覽器有Chrome
/FireFox
/IE
)
1 2 |
//模擬chorme瀏覽器,其他瀏覽器請修改BrowserVersion.後面
WebClient
webClient= new WebClient(BrowserVersion.CHROME);
|
2、查詢特定元素,通過get或者XPath可以從HtmlPage中獲得特定的Html元素,如下例子
方法一,通過get方法獲取
1 2 3 |
//從[煙雨林部落格]上獲取標籤hed的內容
HtmlDivision
div=(HtmlDivision)page.getElementById( "hed" );
|
方法二,通過XPath獲取,XPath通常用於無法通過Id搜尋,或者需要更為複雜的搜尋時,XPath的相關教程
1 2 3 4 |
//同樣可以打印出hed的內容,//div中//表示搜尋整個文件中的div,並將這些div
//放入list中,然後獲取第一個div
final HtmlDivision
div = (HtmlDivision) page.getByXPath( "//div" ).get( 0 );
System.out.println(div.asXml());
|
3、代理伺服器的配置,代理的配置很簡單,只需要配置好地址,埠,使用者名稱與密碼即可
1 2 3 |
final WebClient
webClient = new WebClient(BrowserVersion.CHROME, , 8087 );
final DefaultCredentialsProvider
credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
credentialsProvider.addCredentials( "username" , "password" );
|
4、模擬表單的提交
1 2 3 4 5 6 7 8 9 |
//獲取表單
final HtmlForm
form = page.getFormByName( "form" );
//獲取提交按扭
final HtmlSubmitInput
button = form.getInputByName( "submit" );
//一會得輸入的
final HtmlTextInput
textField = form.getInputByName( "userid" );
textField.setValueAttribute( "test" );
//點選提交表單
|