By
anjia
更新日期:
简介
在英语单词中,phantom [‘fæntəm] 的意思是“幽灵的、幻觉的”。那么,在计算机这里,phantomJS 是个什么东东?
phantomJS 是一个基于 webkit 的服务器端 JavaScript API。它无需浏览器的支持即可实现对 web 的支持,且原生支持各种 web 标准,比如 Dom 处理、JS、CSS、JSON 和 Canvas、SVG。 点击查看更多介绍
可以理解为,phantomJS 是埋伏在后端的不可见的浏览器幽灵。来看看它的非常卡哇伊的图标,有木有很形象的赶脚。左侧是官网的,右侧是打开phantomjs.exe后的任务栏图标,萌萌哒。

安装
npm
用 npm 全局安装,命令:
1
| $ npm install phantomjs -g
|
很方便,且也方便后期和 node 配合。
安装完后,下载的模块在这个目录下:%appdata%\npm\node_modules
当然前提是成功安装了 node 和 npm。当 phantomJS 成功安装后,可以用 —version 查看其版本

其他方式
也可以在 官网 上下载:直接下载一个已经编译好了的二进制包。下载后解压,它的代码其实和用 npm 下载下来的是一样的,也就是目录下的文件夹 %appdata%\npm\node_modules\phantomjs
也可以在 git 上下载,直接 clone 下来。大家可以选择自己习惯的方式去安装。
运行
REPL
REPL,Read-Eval-Print Loop,即自己的虚拟运行环境,即相当于 chrome 的控制台,可以执行任意 JS 代码。
直接打开可执行的文件 phantomjs\lib\phantom\phantomjs.exe,看到的便是 phantomJS 的 REPL 环境。
退出:直接按 ctrl+c,或者执行函数 phantom.exit()

如果是用 npm 安装的 phantomJS,通过命令行进入 phantomJS 提供的完整的 PERL 环境中,如下

执行独立 js
当然,phantomJS 也可以执行一个独立的 js 文件。
方便文件整理,我们专门建立一个文件夹 node_ppp 来存放这些示例文件,执行 add.js

1 2 3 4 5 6 7
| //add.js function add(a,b){ return a+b; } console.log('...add.js'); console.log( add(3,4) ); phantom.exit();
|
语法
简要介绍下 phantomJS 能干什么:
- 加载webpage模块,并创建一个网页实例,打开网页
打开具体网页(默认是get方式,也可以是post-也可以传参数)
- 打开网页后,在页面中执行 JS 代码 page.evaluate()
page.onConsoleMessage() 的回调函数—监听page.evaluate()中写的console语句-以输出到命令行中
- 加载外部脚本 page.includeJS()
- 把网页保存成图片 page.render()
也可以指定浏览器视口的大小,即网页加载的初始浏览器大小
- 当页面上请求资源时…
onResourceRequested 回调函数,当页面请求一个资源时,就会触发
onResourceError 回调函数,当上面的网络请求错误时,包括abort()终止当前的网络请求
- system 模块可加载操作系统变量
更多更详细的内容,可参考 官网 API:
- 命令行接口
- phantom 对象
- web page 模块
- 子进程 模块
- 文件系统 模块
- system 模块
- web server 模块
示例
打开网页+截图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| var webPage = require('webpage'); var page = webPage.create(); page.onConsoleMessage = function(msg){ console.log(msg); } page.viewportSize = { width: 1024, height: 100 }; page.open('http://anjia.github.io', function(status){ console.log(status); var title = page.evaluate(function(){ console.log('This is in evaluate()...'); return document.title; }); console.log('The title of page is: ' + title); page.render('anjia_blog.jpeg', {format:'jpeg', quality:'100'}); phantom.exit(); });
|
运行 test1.js

截图结果太长此处就不贴了,点击查看 anjia_blog.jpeg
从命令行取参+监控 HTTP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| var page = require('webpage').create(); var system = require('system'); if(system.args.length == 1){ console.log('缺少命令行参数,正确的用法是: phantomjs xxx.js http://www.xxx.com'); phantom.exit(); } var req_arr = [], resp_arr = []; var req_flag = resp_flag = true; * 功能:网页请求资源时... * @param requestData 对象-HTTP请求的元数据 * @param networkRequest 对象-发出的网络请求 */ page.onResourceRequested = function(requestData, network){ console.log('request.id:' + requestData.id); req_arr.push(requestData.id); if(req_flag){ console.log('requestData:' + JSON.stringify(requestData)); req_flag = false; } } * 功能:网页收到请求的资源时... * @param response 对象-HTTP请求的元数据 */ page.onResourceReceived = function(response){ console.log('response.id:' + response.id); resp_arr.push(response.id); if(resp_flag){ console.log('response Data:' + JSON.stringify(response)); resp_flag = false; } } var t = Date.now(); var url = system.args[1]; page.open(url, function(status){ if(status==='success'){ t = Date.now() - t; console.log('加载页面用了 '+ t +' ms'); console.log('request 总数:' + req_arr.length + ',如下:' + req_arr.join(',')); console.log('response 总数:' + resp_arr.length + ',如下:' + resp_arr.join(',')); }else{ console.log('页面加载失败...'); } phantom.exit(); });
|
运行 test2.js,用它打开百度的首页 http://www.baidu.com

结果:百度首页的加载用了 271 ms,其中 13 个 request,26 个 response
response 比 request 多,是因为:如果响应的报文太大,会分多次传,此时 onResourceReceived 回调也会被触发多次。
其中,在代码中输出了 requestData 和 responseData,它们都是 JSON 格式。详情可参考 onResourceRequested 和 onResourceReceived。
其他
也可以过滤资源、抓取图片、生成网页,示例代码可查看 参考博客
参考
http://phantomjs.org/quick-start.html
http://javascript.ruanyifeng.com/tool/phantomjs.html
http://www.infoq.com/cn/news/2015/01/phantomjs-webkit-javascript-api