无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的一些工具。