異步網頁采集利器CasperJs


在采集網頁中,我們會經常遇到采集一些異步加載頁面的網頁,我們通常用的httpwebrequest類就采集不到了,這個時候我們通常會采用webbrowser來輔助采集,但是.net下自帶的webbrowser用起來非常不爽,在獲取頁面是否加載完畢的時候比較麻煩一些,DocumentCompleted事件遇到Iframe重復觸發,而且獲取到的源碼通常也不是異步加載完之后的源碼,往往我們需要加上定時器去不斷的檢查,才能獲取到我們想要的源碼。當然我們可以用一些第三方的webkit內核瀏覽器,但是這些判斷頁面是不是真正的加載完成也是比較費勁,而且體積都不小。

今天就介紹一下CasperJSCasperJS是一個開源的導航腳本處理和測試工具,基於PhantomJS 和 slimerjs(前端自動化測試工具)編寫。CasperJS簡化了完整的導航場景的過程定義,提供了用於完成常見任務的實用的高級函數、方法和語法。CasperJS本身的功能很強大,內置了兩種引擎PhantomJS 和 slimerjs 默認使用PhantomJS,具體詳細的功能,大家可以參數這些官方網站去了解,或者加入QQ群389709524一塊討論,今天的重點討論如何快速的采集到異步加載的網頁。

假如我們要采集dudu的這篇文章的評論 http://www.cnblogs.com/dudu/p/csharp-unicode-utf8.html,這篇文章查看源碼是找不到這兩條評論的,我們通過httpwebrequest也是獲取不到的,這個時候我們通過casperjs就非常容易了。

caperjs代碼定義如下:

 1 var fs = require('fs');
 2 var casper = require('casper').create({
 3     pageSettings: {
 4         loadImages: false,
 5         loadPlugins: false
 6     },
 7     logLevel: "debug",//日志等級
 8     verbose: true,    // 記錄日志到控制台
 9 });
10 
11 var url = casper.cli.raw.get('url');
12 
13 //請求頁面
14 casper.start(url, function () {
15     fs.write("temp.html", this.getHTML(), 'w');
16 });
17 
18 casper.run();

 

結果如下:

這樣幾行輕松的代碼就獲取到了異步加載的html代碼了,是不是很簡單,速度也是很快!

當然在實際生產環境中這個還遠遠不夠,我們要考慮各種網站的情景和各種網絡狀況,比如要考慮網絡超時,一個網頁一分鍾加載不了我們就認為超時了,不然會一直等待,還有我們要過濾一下對於我們采集無關的請求,比較谷歌統計,百度統計,廣告等,這個往往會拖慢網頁的加載速度,另外頁面的css樣式,圖片我們通常也不需要,都可以忽略,綜上所述,我們的代碼擴展成這樣子。

  1 var fs = require('fs');
  2 
  3 var casper = require('casper').create({
  4     pageSettings: {
  5         loadImages: true,       
  6         loadPlugins: false,      
  7         userAgent: 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36 LBBROWSER'
  8     },
  9     logLevel: "debug",//日志等級
 10     verbose: true,    // 記錄日志到控制台
 11     timeout: 60000,//60秒超時,退出
 12 });
 13 
 14 
 15 var url = casper.cli.raw.get('url');
 16 
 17 //排除不相關的請求,加快頁面加載進度
 18 casper.on('resource.requested', function(requestData, request) {    
 19     if (requestData.url.indexOf('google-analytics.com') > 0) {
 20         request.abort();
 21     }
 22     if (requestData.url.indexOf('googlesyndication.com') > 0) {
 23         request.abort();
 24     }
 25     if (requestData.url.indexOf('hm.baidu.com') > 0) {
 26         request.abort();
 27     }
 28     if (requestData.url.indexOf('baidustatic.com') > 0) {
 29         request.abort();
 30     }
 31     if (requestData.url.indexOf('share.baidu.com') > 0) {
 32         request.abort();
 33     }
 34     if (requestData.url.indexOf('cbjs.baidu.com') > 0) {
 35         request.abort();
 36     }
 37     if (requestData.url.indexOf('jiathis.com') > 0) {
 38         request.abort();
 39     }
 40     if (requestData.url.indexOf('.cnzz.com') > 0) {
 41         request.abort();
 42     }
 43     if (requestData.url.indexOf('.51.la') > 0) {
 44         request.abort();
 45     }
 46     if (requestData.url.indexOf('.tanx.com') > 0) {
 47         request.abort();
 48     }
 49     //this.echo("==============>page.resource.requested"+requestData.url);
 50 });
 51 
 52 //超時執行的函數,記錄到日志文件
 53 casper.on('timeout', function () {
 54     //this.echo("===>timeout"+url);
 55     var fileName = this.evaluate(getFileName);
 56     var nowTime = this.evaluate(CurentTime);
 57     fs.write("log/timeout_" + fileName + ".txt", nowTime + "====>" + url + "\r\n", 'a');
 58 });
 59 
 60 //請求頁面
 61 casper.start(url, function () {
 62     var status = this.status().currentHTTPStatus;
 63     //this.capture('tt.png');
 64     fs.write("temp.html", this.getHTML(), 'w');
 65 });
 66 
 67 
 68 function getFileName() {
 69     var now = new Date();
 70 
 71     var year = now.getFullYear();       //
 72     var month = now.getMonth() + 1;     //
 73     var day = now.getDate();            //
 74 
 75     return (year + "" + month + "" + day);
 76 }
 77 
 78 function CurentTime() {
 79     var now = new Date();
 80 
 81     var year = now.getFullYear();       //
 82     var month = now.getMonth() + 1;     //
 83     var day = now.getDate();            //
 84 
 85     var hh = now.getHours();            //
 86     var mm = now.getMinutes();          //
 87 
 88     var clock = year + "-";
 89 
 90     if (month < 10)
 91         clock += "0";
 92 
 93     clock += month + "-";
 94 
 95     if (day < 10)
 96         clock += "0";
 97 
 98     clock += day + " ";
 99 
100     if (hh < 10)
101         clock += "0";
102 
103     clock += hh + ":";
104     if (mm < 10) clock += '0';
105     clock += mm;
106     return (clock);
107 }
108 
109 casper.run();
View Code

CasperJs的安裝,可以參考官方網站的文檔,或者關注下面的微信公眾號 提供本文的所有工具和源碼下載,本人也是最近剛接觸,希望和大家一塊討論。今天寫此文章還有個目的是,使用CasperJs的時候遇到一個頁面個別文字出現亂碼,一時找不到解決方案,歡迎知道的大俠幫忙指點下!情景如下:

比如采集這個網頁 http://meiri.jguo.cn/mryr/2014/1209/59249.html  這個網站編碼是gb2312 采集的時候遇到 曹叡 的 “叡 ”會出現亂碼,其他的文字沒事,我自己測試了下,發現如果網站是utf-8編碼的,采集的時候這個字沒問題,但是咱們是采集程序,不可能要求別人改編碼,所以目前還沒有想到解決方案,還希望知道的同學,指點一二,在此謝了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM