無UI界面基于WebKit內核的瀏覽器phantomJS介紹
什么是phantomJS?
最近一直在研究關于Headless browsers一些東西,最先接觸到的就是相當有名的 phantomJS ,無UI界面,基于WebKit內核,多用于在JS測試的一些方面,當然還有網絡監控,網頁截圖等。以JS為結尾,但它既不是一個node的模塊,也不是一個普通的js的庫。這個JS和Node.js的js類似含義,運行javascript,CommonJS規范,由幾個phantomjs自有的模塊和一些node里功能差不多的模塊(child_process ,fs,system等)構成。當使用phantomJS加載了一個頁面時候,你就可以對這個頁面做你任何想要的事情了,增加cookie,注入js,操作DOM等等。
官網的例子:
// Simple Javascript example console.log('Loading a web page'); var page = require('webpage').create(); var url = 'http://phantomjs.org/'; page.open(url, function (status) { //Page is loaded! phantom.exit(); });
運行:
phantomjs hello.js
很多人會問為什么不做成一個node的模塊,官網上的回答: http://phantomjs.org/faq.html 最后第二個問題
使用phantomJS
項目需求是使用phantomJS捕獲所加載頁面的所有http請求生成一個har格式文件進行分析,官網上直接提供了一個例子 netsniff.js ,因為只能捕獲到瀏覽器觸發onload事件,想獲取到更多請求信息就自己改造了下。但網絡請求信息方面,畢竟不是真實的瀏覽器環境,所以信息不太準確,具體問題有:gzip壓縮文件大小問題,http請求信息不全,同一個頁面onload時間有時差別會很大, 不支持flash(官方解釋由于違背了headless,和各種issues和bugs)。
phantomJS提供了Mac OX S和Windows的可執行文件,linux因為一些原因還沒有提供,只能拿源代碼自己編譯,因為linux系統版本不同編譯出來大多不能通用,目前已經測試centos6編譯的版本不兼容centos7上運行,不同發型版本的linux應該更加不一。
phantomJS做一個js的自動化測試或者對請求信息要求不高的事情還是想當不錯的,提供的API豐富,所以出現了很多基于phantomJS平臺的很有趣的項目,比如Casper.js等等 http://phantomjs.org/related-projects.html
Headless browsers
就像瀏覽器,phantomJS的內核是基于webkit。所以就出現了基于Gecko內核的 SlimerJS ,支持自己手動指向操作系統里面安裝的firefox版本或者直接使用它提供的XulRunner,支持運行firefox的插件(flash等)。和使用 .NET WebBrowser Class 利用v8引擎的 triflejs , 沒怎么關注,因為基于.NET好像只能跑在windows上。 API基本兼容phantomJS的API,有一些不同官網也有詳細說明 Differences with PhantomJS 。
個人感覺,phantomJS到2.0版本,不支持flash對有flash的網站其實不是很友好,雖然Github上有個人fork出了分支寫了個支持flash的版本,但是好像沒怎么更新了。SlimerJS,支持運行插件,可能會比phantomjs能做的事情多一些,也安裝運行過,感覺還是有很多詭異的問題, 還沒1.0的版本。triflejs,用的人比較少,沒怎么研究。
衍生,思考
因為比較上面幾個都不是真實的瀏覽器環境,所以必定會有各種各樣的問題出現。比起在安裝真實瀏覽器的情況下去運行測試js、收集信息,就會比較可靠。
xvfb
linux下的一個工具,提供了一個容器,可以讓程序在無界面的情況下執行,所以你可以這樣訪問一個網頁:
xvfb-run firefox https://www.google.com
推薦文章: http://tobyho.com/2015/01/09/headless-browser-testing-xvfb/
Selenium
另一個web應用測試的世界,功能強大,社區完整,完全模擬真實瀏覽器的環境。有想過基于它來做,但是使用和安裝成本比phantomJS高,暫時擱淺。
Remote debugging protocol
Remote debugging protocol ,無意中在stackoverflow中發現一個方案,是chrome官方提供的一個遠程訪問的使用方法。在任何一臺機器上只要裝了chrome,用命令行形式開啟一個進程
chrome.exe --remote-debugging-port=9222 --user-data-dir=<some directory>
會自動打開一個chrome,然后就可以使用 chrome-remote-interface ,一個node.js的模塊來操作9222端口的chrome,完全模擬真實的訪問。但是提供的功能API比較簡單,而且該協議不支持同時打開多個頁面,一次只能一個客戶端連接。
BrowserMob Proxy
capture performance data from browsers,用的是java,不太熟悉,所以也沒嘗試。
stackoverflow
stackoverflow 上的一個回答,列出了很詳細的Headless Browser的一些工具。