將網頁內容另存圖檔是專案裡三不五時會冒出的需求,但一直沒找到順手好使的兵刃。

不久前介紹過HTML轉PDF的元件 -- Pechkin套件,網頁存成PDF已多少有保留擷圖的意義,但文末對本部落格的實測讓人失望,失真嚴重。最近的專案又被逼著設法將現成網頁(由JavaScript動態產生內容)轉存圖檔供其他系統應用,省去另外開發匯出模組的工程。再次Survey解決方案,想起先前流浪小風在Chutzpath介紹提過另一個webkit核心的網頁操作引擎 – PhantomJs

小試之後驚為天人,簡便易用卻威力無窮,PhantomJs可輕易實現以下功能:

  1. 不依賴任何瀏覽器,直接以命令列工具方式載入網頁,並開放以指令存取網頁DOM。這個基礎建立後,衍生的好玩應用就多了。
  2. 能操作DOM物件並檢查結果,要做到網頁自動測試不是夢。(有個術語叫Headless Website Testing,意指不需瀏覽器不顯示任何網頁UI就完成測試)
  3. 一行指令就能將網頁顯示結果另存成圖檔。
  4. 除了HTML5及CSS3,還支援Canvas及SVG。
  5. 監控DOM載入及AJAX傳輸過程,進行效能分析。
  6. 提供互動式操作模式(REPL),可逐次下指令、看結果,即興演出。
  7. 除了測試網頁,撰寫程式操作網頁還能用來幹些邪惡的勾當執行特殊任務,例如: 搶春節車票、在馬拉松報名秒殺戰裡突圍、發動網路灌票... 等等。理論上用瀏覽器外掛或寫程式模擬POST Request也能達成相同效果,用PhantomJs在效能及簡便性上具一定的優勢。

使用PhantomJs不需安裝,到網站下載ZIP檔,解壓縮後有個phantomjs.exe,靠它就可以開始變戲法。例如,將以下幾行程式存成lab.js,放在phantomjs.exe同目錄下,開啟命令列視窗,CD路徑到phantomjs.exe所在資料夾,執行phantomjs lab.js,就能抓取本部落格的擷圖:

排版顯示純文字
var page = require('webpage').create();
page.open('http://blog.darkthread.net', function() {
    page.render('d:\\darkthread.png');
    phantom.exit();
});

產生的圖檔十分逼近網頁的實際檢視結果! (主要只差Flash部分無法顯示)

另外,我還寫了一個簡單的Canvas + SVG測試網頁,用PhantomJs也成功儲存顯示結果,令人感動到起雞皮疙瘩~

新武器入手,未來搞網站自動測試、綱頁擷圖、為非作歹突圍奇襲又多了神兵利器可用。啊~~ 福氣啦!


Comments

# by 冰原光

黑暗大, 請問如果是在抓取正在執行(例如使用者已做了一些操作) (像是pchome的已購買物品網頁照相)中的網頁, 是否也可用此套件? 謝謝.

# by Jeffrey

to 冰原光, 你說的情境,可以透過"連到某URL -> 執行JavaScript程式模擬使用者操作 -> 建立快照圖檔"達成,技術上絕對可行。

# by 冰原光

黑暗大, 如果是想對使用者'當時看到系統上的錯誤'做一個快照, 又要如何達成? 謝謝. *ps, 您的系統時間怪怪的, 留言時間應為AM才是.

# by Jeffrey

to 冰原光,一般而言,使用者遇到系統錯誤都是在當下的時空條件配合下產生,即使在同一台機器再做第二次相同操作,都不一定能重現,依經驗,請使用者擷取桌面存檔是較穩當的方法。但有另一個角度,如果系統錯誤發生在Server端(HTTP 500),只要系統架構設定妥當,可以將每一則Exception的細節忠實保留,會比要求使用者提供更易掌握。 留言時間不對的問題與我的Hosting主機在國外有關,但我一直沒徹底調整排除,只好請大家忍著點。(把頭繼續埋進沙裡)

# by jhw

验证码怎么破解呢。。。。

# by Jeffrey

to jhw, 所謂的驗證是指輸入帳號、密碼的表單驗證? 還是指CAPTCHA? 前者理論上模仿使用者填入資料按鈕送出即可,後者的話已涉及Hacking,就是另外一門學問了。

# by 蝦米

似乎很好玩 可否寫更多的介紹呢 謝謝

Post a comment