文章目录
  1. 1. 简介
  2. 2. 安装
    1. 2.1. npm
    2. 2.2. 其他方式
  3. 3. 运行
    1. 3.1. REPL
    2. 3.2. 执行独立 js
  4. 4. 语法
  5. 5. 示例
    1. 5.1. 打开网页+截图
    2. 5.2. 从命令行取参+监控 HTTP
    3. 5.3. 其他
  6. 6. 参考

简介

在英语单词中,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 能干什么:

  1. 加载webpage模块,并创建一个网页实例,打开网页
    打开具体网页(默认是get方式,也可以是post-也可以传参数)
  2. 打开网页后,在页面中执行 JS 代码 page.evaluate()
    page.onConsoleMessage() 的回调函数—监听page.evaluate()中写的console语句-以输出到命令行中
  3. 加载外部脚本 page.includeJS()
  4. 把网页保存成图片 page.render()
    也可以指定浏览器视口的大小,即网页加载的初始浏览器大小
  5. 当页面上请求资源时…
    onResourceRequested 回调函数,当页面请求一个资源时,就会触发
    onResourceError 回调函数,当上面的网络请求错误时,包括abort()终止当前的网络请求
  6. system 模块可加载操作系统变量

更多更详细的内容,可参考 官网 API

  1. 命令行接口
  2. phantom 对象
  3. web page 模块
  4. 子进程 模块
  5. 文件系统 模块
  6. system 模块
  7. 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
//test1.js
//webpage 模块主要用于网页操作,是PhantonJS的核心模块
var webPage = require('webpage');
var page = webPage.create();//创建一个网页实例
//onConsoleMessage() 回调函数 [以输出evaluate()方法中的console]
page.onConsoleMessage = function(msg){
console.log(msg);
}
//设置宽
page.viewportSize = {
width: 1024,
height: 100
};
//open() 打开具体网页,默认是get方法
page.open('http://anjia.github.io', function(status){
//表示状态的字符串 [只要收到服务器的返回结果,就会认为成功-而不管400/500]
console.log(status);
//evaluate() 打开网页后,在页面中执行JS代码
var title = page.evaluate(function(){
//网页内部和evaluate()内部的console语句,默认不会显示在命令行中
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
//test2.js
var page = require('webpage').create();
var system = require('system'); //system 模块-加载操作系统的变量
//命令行参数校验
if(system.args.length == 1){
console.log('缺少命令行参数,正确的用法是: phantomjs xxx.js http://www.xxx.com');
phantom.exit();
}
//数组,分别存 request 和 response 的 id
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 格式。详情可参考 onResourceRequestedonResourceReceived

其他

也可以过滤资源、抓取图片、生成网页,示例代码可查看 参考博客

参考

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

文章目录
  1. 1. 简介
  2. 2. 安装
    1. 2.1. npm
    2. 2.2. 其他方式
  3. 3. 运行
    1. 3.1. REPL
    2. 3.2. 执行独立 js
  4. 4. 语法
  5. 5. 示例
    1. 5.1. 打开网页+截图
    2. 5.2. 从命令行取参+监控 HTTP
    3. 5.3. 其他
  6. 6. 参考