浅陌游离 2016-11-15
无头浏览器即headless browser,是一种没有界面的浏览器。既然是浏览器那么浏览器该有的东西它都应该有,只是看不到界面而已。
Webkit:目前最主流的浏览器内核,webkit是苹果公司开源的浏览器内核,其前身是KHTML。基于Webkit的浏览器很多,比如Safari,Chrome,Opera
Gecko:是Firefox浏览器的内核
Trident:是IE浏览器的内核
Blink:是webkit的一个分支版本,由google开发
Webkit无疑是目前最流行的浏览器内核,以Webkit为核心存在很多移植(port),包括Safari、iPhone、Chrome、Android、QTWebKit等。不同的port专注于不同的领域。Mac的port注意力集中在浏览器和操作系统的分割上,允许把ObjectC和C++绑定并嵌入原生应用的渲染。Chromium专注在浏览器上。QtWebKit的port在他的跨平台GUI应用架构上给apps提供运行时环境或者渲染引擎。
PhantomJS可以说是目前使用最为广泛,也是最被认可的无头浏览器。由于采用的是Webkit内核,因此其和目前的Safari,Chrome等浏览器兼容性十分好。
PhantomJS的安装十分简单,下载http://phantomjs.org/download.html,下载下来后解压即可。编写测试代码test.js
var page = require('webpage').create(); page.open('http://example.com', function(status) { console.log("Status: " + status); console.log(page.content); phantom.exit(); });
bin\phantomjs.exe test.js,如果status返回success即成功。通过page.content即可获得下载并渲染好的网站内容。
前面说过,PhantomJS和NodeJS是平等的关系,如果说NodeJS把javascirpt引擎V8挪到服务器端,PhantomJS则把WebKit整个引擎都挪到了服务器端。
在nodejs中使用phantomjs,需要用到phantomjs中的一个Child Process模块,介绍在这里http://phantomjs.org/api/child_process/。
庆幸的是万能的github已经有对phantomjs的node支持库,项目地址在这里https://github.com/amir20/phantomjs-node
PhantomJs和java的结合使用目前还比较麻烦,主要还是直接调用phantomjs执行,如:
Runtime rt = Runtime.getRuntime(); Process p = rt.exec("phantomjs /Users/cxs/utils/phantomjs/codes.js "+url);
既然nodejs可以通过child_process实现与phantomjs的交互,那么java为啥不行呢?目前还没有找到相应的实现,笔者也在研究这块,希望能提供一个java的实现。
可以利用Web服务,在phantomjs中启动一个微型web服务,java进程往这个web服务发送数据及接受处理完成的结果。web服务有两个方式:
那么在java环境下有没有一款完全兼容webkit的无头浏览器呢?笔者目前还没有找到任何一款这样的浏览器。要实现这样的浏览器有三个思路:
HtmlUnit是一款纯java开发的无头浏览器,他既没有用weibkit内核,也没用gecko内核,其dom解析、css解析、javascript解析都是纯java开发的,因此其兼容性不太理想。
目前HtmlUnit的最新版本的javascript引擎使用的是一款很老的叫做Rhnio的引擎,不管在效率和兼容性上都不理想。在java8中已经使用Nashorn代替Rhnio引擎,Nashorn完全支持ECMAScript 5.1规范,但是笔者尝试用Nashorn代替Rhnio使用HtmlUnit,还是不能有效的解析JQuery这种十分流行的js框架。
既然PhantomJS可以利用QtWebkit开发出无头浏览器,为啥不能用java结合QtWebkit开发同样的无头浏览器呢,笔者在github上建了一个项目https://github.com/xtuhcy/webkit4j,目前在window环境下已经能成功调用qtwebkit,也希望有兴趣的朋友能一起参与讨论。