沒錯,最后我還是使用了Selenium,去實現上一篇我所說的問題,別的沒有試,只試了一下firefox的引擎,總體效果對我來說還是可以接受的。
繼續昨天的話題,既然要實現上篇所說的問題,那么就需要一個可以執行js代碼的框架。我首先選擇的是htmlunit,先簡單介紹一下htmlunit。下面一段摘自網絡。
htmlunit 是一款開源的 java 頁面分析工具,啟動 htmlunit 之后,底層會啟動一個無界面瀏覽器,用戶可以指定瀏覽器類型:firefox、ie 等,如果不指定,默認采用 INTERNET_EXPLORER_7: WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6); 通過簡單的調用: HtmlPage page = webClient.getPage(url); 即可得到頁面的 HtmlPage 表示,然后通過: InputStream is = targetPage.getWebResponse().getContentAsStream() 即可得到頁面的輸入流,從而得到頁面的源碼,這對做網絡爬蟲的項目來說,很有用。 當然,也可以從 page 中得更多的頁面元素。 很重要的一點是,HtmlUnit 提供對執行 javascript 的支持: page.executeJavaScript(javascript) 執行 js 之后,返回一個 ScriptResult 對象,通過該對象可以拿到執行 js 之后的頁面等信息。默認情況下,內部瀏覽器在執行 js 之后,將做頁面跳轉,跳轉到執行 js 之后生成的新頁面,如果執行 js 失敗,將不執行頁面跳轉。 |
最后可以取得page.executeJavaScript(javascript).getNewPage(),獲取執行后的頁面。換句話說,javascript需要在這里人為的執行,顯然與我的初衷不符,另外可能是我水平太差,在抓取sina新聞的頁面時總是出錯,暫時還沒發現錯誤在何處,但按照網絡上查詢的結果來分析,極有可能錯誤的原因是在於htmlunit執行某些帶參數的請求時,由於參數的順序或者編碼問題會導致請求失敗而報錯。關鍵是,運行后並沒有得到我需要的結果。
那么就另尋解決辦法,這個時候就找到了Selenium WebDriver,他是我需要的一個解決方案。
參考了資料和例子,就可以開始使用他了。實例代碼如下。
1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"); 2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary); 3 FirefoxProfile firefoxProfile = new FirefoxProfile(); 4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile); 5 6 7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064"); 8 9 ArrayList list = new ArrayList(); 10 list.add("http://www.sina.com.cn"); 11 list.add("http://www.sohu.com"); 12 list.add("http://www.163.com"); 13 list.add("http://www.qq.com"); 14 15 long start,end; 16 17 for(int i=0;i<list.size();i++){ 18 start = System.currentTimeMillis(); 19 driver.get(list.get(i).toString()); 20 end = System.currentTimeMillis(); 21 System.out.println(list.get(i).toString() + ":" + (end - start)); 22 } 23 24 driver.close();
使用了firefox的引擎,得到的結果如下,而且確實滿足了我的要求。
http://www.sina.com.cn:6638
http://www.sohu.com:5796
http://www.163.com:7567
http://www.qq.com:9384
可以看見如上的結果時間還是蠻長的,那如何加快速度呢。其實仔細考慮一下,為什么他要這么久,就是因為他在下載網頁元素,我們請求一個網站的時候是發起一個req,得到一個res,而res中是只有元素沒有內容的,換句話說,他不用執行css,js,不用下載圖片,flash,加載廣告等等。而如果我們需要加快效率,那就需要移除一切與我分析無關的東西,那么仿照瀏覽器一樣,我們需要屏蔽掉css,圖片,flash等等,從而加速網頁的速度,更關心其中的內容。
簡單方法如下:
1 //去掉css
firefoxProfile.setPreference("permissions.default.stylesheet", 2); 2 //去掉圖片 3 firefoxProfile.setPreference("permissions.default.image", 2); 4 //去掉flash
firefoxProfile.setPreference("dom.ipc.plugins.enabled.libflashplayer.so",false);
那么在去除掉所有firefox緩存后,再次運行一下,會有什么結果呢。結果如下
http://www.sina.com.cn:5085
http://www.sohu.com:3520
http://www.163.com:3329
http://www.qq.com:2048
發現確實快了很多。上面只是一個大致的原型,如果真正的要用,還需要封裝。