天天看點

PhantomJS(webkit)/SlimerJS (Gecko) + CasperJS擷取JavaScript渲染後的網頁内容

前言:

對于富用戶端的 Web 應用頁面,自動登入、頁面修改、抓取頁面内容、螢幕截圖、頁面功能測試…面對這些需求,使用後端語言需要花費不少的精力才能實作, 通常這是因為這些網站會判斷通路站點的用戶端是否是一個真實的浏覽器,此時 SlimerJS、phantomJS 或 CasperJS 或許是更好的一種選擇。

使用PhantomJS(webkit)或者SlimerJS (Gecko) 配合 CasperJS擷取JavaScript渲染後的網頁内容以及内嵌子(iFrame 裡的内容)網頁渲染後的内容, 那麼這樣做到底能為我們做什麼?壞笑,我就不多說了,當然是來幫我分析解決網頁的問題了,然後是網絡爬蟲,還能做什麼不好的事?相信大家是可意會不可言傳,不就是這麼不言而喻嗎!!

要實作這些功能,除了 使用PhantomJS(webkit)或者SlimerJS (Gecko) 配合 CasperJS以外,當然還有其他途徑了。如下(至于孰優孰劣在下不做任何評論,各位看官自己研究研究吧):

基于chromiun的swing元件

http://www.teamdev.com/jxbrowser

Swing使用JavaFX的方式

http://www.tuicool.com/articles/N7J3au

http://docs.oracle.com/javafx/2/webview/jfxpub-webview.htm

DJ NativeSwing

非常強大,可以使用IE、 Firefox, XULRunner or Webkit

http://gongqi.iteye.com/blog/754231

http://sourceforge.net/projects/djproject/

XULRunner方式

http://wiki.netbeans.org/EmbeddedBrowser

基于MozSwing(獨立運作,不依賴客戶機器的浏覽器版本)

看參看博文:http://blog.csdn.net/lxf9601/article/details/6967167

該博文的源碼:http://download.csdn.net/detail/lxf9601/3808104

該博文源碼的相關說明:http://blog.csdn.net/lxf9601/article/details/6985848

pyquery

python的一個jquery庫, http://pythonhosted.org//pyquery/api.html

介紹:

1、PhantomJS

源碼:https://github.com/ariya/phantomjs

官網:http://phantomjs.org/ (說明文檔和api都可以從官網上找到)

目前最新版本 2.1.1.

PhantomJS是一個基于WebKit的伺服器端JavaScript API,它基于 BSD開源協定釋出。PhantomJS無需浏覽器的支援即可實作對Web的支援,且原生支援各種Web标準,如DOM 處理、JavaScript、CSS選擇器、JSON、Canvas和可縮放矢量圖形SVG。PhantomJS主要是通過JavaScript和CoffeeScript控制WebKit的CSS選擇器、可縮放矢量圖形SVG和HTTP網絡等各個子產品.

PhantomJS應用于:

  • 1.無需浏覽器的Web測試:支援很多測試架構,如YUI Test、Jasmine、WebDriver、Capybara、QUnit、Mocha
  • 2.頁面自動化操作:使用标準的DOM API或一些JavaScript架構(如jQuery)通路和操作Web頁面。
  • 3.螢幕捕獲:以程式設計方式抓起CSS、SVG和Canvas等頁面内容,即可實作網絡爬蟲應用。建構服務端Web圖形應用,如截圖服務、矢量光栅圖應用。
  • 4.網絡監控:自動進行網絡性能監控、跟蹤頁面加載情況以及将相關監控的資訊以标準的HAR格式導出。

基于PhantomJS的擴充包:

  • CasperJS:一個開源的導航腳本處理和進階測試工具
  • Poltergeist :測試工具Capybara的測試驅動
  • Guard::Jasmine:能夠基于Rails實作自動化測試Jasmine的Specs
  • GhostDriver:遠端 WebDriver 有線協定的開源實作
  • PhantomRobot:PhantomJS機器人測試架構
  • Mocha-PhantomJS:JavaScript測試架構Mocha的用戶端
  • capturejs、pageres、phantomjs-screenshots、manet、screenshot-app : 截屏工具

使用方式:

  • 1.官網下載下傳phantomjs,包括 Windows ,Mac OS,Linux版本,自行選擇對應 版本下載下傳解壓即可,其中帶有一個example檔案夾,裡面有很多已經寫好的代碼供使用。
  • 2.配置環境變量:在環境變量path中添加phantomjs的bin路徑
  • 3.編寫自己腳本,使指令:phantomjs 腳本路徑 運作。

例子:

console.log('Hello, world!');
phantom.exit();
           

儲存為hello.js, 執行:phantomjs hello.js

輸出結果為:Hello, world!

2、SlimerJS

源碼:https://github.com/laurentj/slimerjs

官網:https://slimerjs.org

幫助文檔:http://docs.slimerjs.org/current/

使用 slimerjs 抓取 DDos 保護的站點: http://www.tuicool.com/articles/myqAF3

SlimerJS 是一個提供給 Web 開發人員,一個基于WebKit的伺服器端JavaScript API,可通過腳本程式設計控制的浏覽器。它可以讓你使用 Javascript 腳本操縱一個網頁:打開一個網頁,點選連結,修改的内容等,這對于做功能測試,頁面自動機,網絡監控,螢幕捕獲等是非常有用的。

事實上,它是類似 PhantomJS 的一個工具,但是 SlimerJS 隻能運作在 Gecko (Firefox)上而不是Webkit。SlimerJS 提供幾乎和 PhantomJS 相同的 API,高度相容 PhantomJS。SlimerJS 不僅是 PhantomJS 的一個克隆,還包含額外的功能。其文法與PhantomJS幾乎沒有任何差别,高度相容相容 CasperJS。

與PhantomJS 的差別

  • PhantomJS 基于 Webkit 核心,不支援 Flash 的播放
  • SlimerJS 基于火狐的 Gecko 核心,支援 Flash播放,并且執行過程會有頁面展示

功能(幾乎可以使用 javascript 模拟在浏覽器上的任何操作)

  • 1.打開頁面
  • 2.前進/後退
  • 3.頁面點選
  • 4.滑鼠滾動
  • 5.DOM 處理
  • 6.CSS 選擇器
  • 7.Canvas 畫布
  • 8.SVG畫圖

使用方式(和PhantomJS 的使用法方式沒有差別):

  • 1.官網下載下傳SlimerJS ,解壓
  • 2.配置環境變量:在環境變量path中添加SlimerJS 的bin路徑
  • 3.編寫自己腳本,使指令:slimerjs 腳本路徑 運作。

實作頁面的某個區域截圖,SlimerJS 與PhantomJS 的示例

SlimerJS 示例

var webpage = require('webpage').create();
webpage.open('http://www.meizu.com') // 打開一個網頁
.then(function() { // 頁面加載完成後執行
    //儲存頁面截屏
    webpage.viewportSize = {
        width: ,
        height: 
    };
    webpage.render('page.png', {
        onlyViewport: true
    });
    //再打開一個網頁
    return webpage.open('http://bbs.meizu.com');
})
.then(function() {
    // 點選某個位置
    webpage.sendEvent("click", , , 'left', );
    slimer.exit(); //退出
});
           

PhantomJS 示例

var webpage = require('webpage').create();
webpage.open('http://www.meizu.com', function (status) {
  //打開一個頁面
}).then(function(){
    //儲存頁面截屏
    webpage.viewportSize = {
        width: ,
        height: 
    };
    webpage.render('page.png', {
        onlyViewport: true
    });
    //再打開一個網頁
    return webpage.open('http://bbs.meizu.com');
}).then(function(){
    webpage.sendEvent("click", , , 'left', );
    phantom.exit();
});
           

3、CasperJS

源碼:https://github.com/casperjs/casperjs

官網:http://casperjs.org/

幫助文檔:http://docs.casperjs.org/en/latest/

目前版本 1.1.3。

CasperJS 是一個開源的導航腳本和測試工具,使用 JavaScript 基于 PhantomJS 編寫,用于測試 Web 應用功能,Phantom JS是一個伺服器端的 JavaScript API 的 WebKit。其支援各種Web标準: DOM 處理, CSS 選擇器, JSON, Canvas, 和 SVG。

CasperJS 按照start()、then*()、wait*()、open()等流程往下做導航(注意,如果有文法錯誤,比如少個分号神馬的,可能運作時就無任何提示的卡那裡了)

run()方法觸發該流程,run()方法可以指定一個onComplete()方法供導航完成時回調

exit()/die()退出

this.getPageContent() 可以檢視渲染後的頁面内容

它提供了一套用于 Web 應用測試的方法元件,這些元件基于 PhantomJS 或 SlimerJS 所提供的 javascript API,實作對 Web 應用的功能執行。CasperJS 簡化了完整的導航場景的過程定義,提供了用于完成常見任務的實用的進階函數、方法和文法。如:

  • 定義和整理導航步驟
  • 表單填充
  • 點選、跟蹤連結
  • 區域、頁面截圖
  • 斷言遠端DOM
  • 日志、事件
  • 資源下載下傳,包括二進制資源
  • 捕捉錯誤,并做出相應的響應
  • ……

使用方式:

  • 1.依賴PhantomJS, 是以需要先安裝好PhantomJS,并且配置好PhantomJS的環境變量。
  • 2.官網下載下傳CasperJS ,解壓到指定位置,配置環境變量, 同PhantomJS的環境變量配置方式一樣
  • 3.指令:casperjs -version 檢視是否安裝成功
  • 4.運作:casperjs 腳本

CasperJS 前端自動化測試腳本 示例:

var utils = require('utils');
var webpage = require('casper').create({
    //verbose: true,
    logLevel: 'debug',
    viewportSize: {
        width: ,
        height: 
    },
    pageSettings: {
        loadImages: true,
        loadPlugins: true,
        XSSAuditingEnabled: true
    }
});

//打開頁面
webpage.start()
    .thenOpen('http://www.meizu.com', function openMeizu(res) {
        this.echo('列印頁面資訊');
        res.body = '';//不列印body資訊
        utils.dump(res);
        //點選登入按鈕
        if (this.exists("#_unlogin")) {
            this.echo('點選登入按鈕');
            this.click("#_unlogin a:nth-child(1)");
            this.wait(, function wait3s_1() {
                if (this.exists("form#mainForm")) {
                    this.echo("需要登陸,填充賬号資訊。。。");
                    //填充表單賬号
                    this.fill('form#mainForm', {
                        'account': '[email protected]',
                        'password': '********'
                    }, true);
                    this.capture('meizu_login_page.png');
                    this.wait(, function wait3s_2() {
                        //登入按鈕存在,點選
                        if (this.exists("#login")) {
                            this.echo('送出登入');
                            this.click("#login");
                        }
                    });
                }
            });
        }
    })
    .then(function capture() {
        if (this.exists('#mzCustName')) {
            this.echo('登入成功!開始截圖存儲..');
        } else {
            this.echo('登入失敗!請檢視截圖檔案')
        }
        //截圖
        this.capture('meizu.png');
        this.captureSelector('meizu_header.png', 'div.meizu-header');
    })
    .then(function exit() {
        this.echo('執行完成,退出');
        this.exit();
    })
    .run();
           

CasperJS 抓取 Javascript 渲染的網頁 示例:

下面的代碼,會抓取網易雲音樂的頁面,運作Javascript,然後把最終的HTML儲存在文本裡。

// http://casperjs.org/

var casper = require('casper').create({
  pageSettings: {
    loadImages:  false, // 不加載圖檔,減少請求
  }
});

var fs = require('fs');

casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36');

casper.start();
casper.viewport(, );

casper.then(function() {
    this.open('http://music.163.com/#/m/discover/artist/').then(function(){
      this.page.switchToChildFrame(); // 頁面包含 iFrame
      fs.write("1.html", this.getPageContent(), 'w');  // 儲存 iFrame 裡的内容

      this.page.switchToParentFrame();
      fs.write("2.html", this.getPageContent(), 'w');
    });
});

casper.run();
           

CasperJS 循環調用示例:

解決方案是遞歸調用,casperjsObj調用run函數時可以傳入一個結束時執行的函數,在這個函數裡面可以加入【我們的循環體】和【遞歸的run調用】

function refresh()  
{  
        this.wait(,  
                function() {  
                        this.click('a[title="履歷重新整理"]');  
                        this.log('refreshed my resume');  
                }  
        );  
        this.run(refresh);  
}  
casper.run(refresh);  
           

日志中出現”Unsafe JavaScript attempt to access frame with URL”的info資訊,啟動casperjs時候加上參數–web-security=false(allow cross-domain XHR)即可(參見http://stackoverflow.com/questions/18960791/cant-run-a-basic-test-with-casperjs)

要治本的話,參見http://stackoverflow.com/questions/4324108/unsafe-javascript-attempt-to-access-frame-with-url

繼續閱讀