PhantomJS

PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎。它原生支持多种web 标准:DOM 操作,CSS选择器,JSON,Canvas 以及SVG。

官方网站:

http://phantomjs.org/download.html

Examples:

http://phantomjs.org/examples/index.html

安装完成之后命令行输入

phantomjs -v

如果正常显示版本号,那么证明安装成功了。如果提示错误,那么请重新安装。

快速开始

第一个程序

第一个程序当然是Hello World,新建一个 js 文件。命名为 helloworld.js

  1. console.log('Hello, world!');
  2. phantom.exit();

命令行输入

  1. phantomjs helloworld.js

程序输出了 Hello,world!程序第二句话终止了 phantom 的执行。

注意:phantom.exit();这句话非常重要,否则程序将永远不会终止。

页面加载

可以利用 phantom 来实现页面的加载,下面的例子实现了页面的加载并将页面保存为一张图片。

  1. var page = require('webpage').create();
  2. page.open('http://example.com', function (status) {
  3. console.log("Status: " + status);
  4. if (status === "success") {
  5. page.render('example.png');
  6. }
  7. phantom.exit();
  8. });

首先创建了一个webpage对象,然后加载本站点主页,判断响应状态,如果成功,那么保存截图为 example.png

以上代码命名为 pageload.js,命令行

  1. phantomjs pageload.js

发现执行成功,然后目录下多了一张图片,example.png

PhantomJS渲染 - 图1

因为这个 render 方法,phantom 经常会用到网页截图的功能。

测试页面加载速度

下面这个例子计算了一个页面的加载速度,同时还用到了命令行传参的特性。新建文件保存为 loadspeed.js

  1. var page = require('webpage').create(),
  2. system = require('system'),
  3. t, address;
  4. if (system.args.length === 1) {
  5. console.log('Usage: loadspeed.js <some URL>');
  6. phantom.exit();
  7. }
  8. t = Date.now();
  9. address = system.args[1];
  10. page.open(address, function(status) {
  11. if (status !== 'success') {
  12. console.log('FAIL to load the address');
  13. } else {
  14. t = Date.now() - t;
  15. console.log('Loading ' + system.args[1]);
  16. console.log('Loading time ' + t + ' msec');
  17. }
  18. phantom.exit();
  19. });

程序判断了参数的多少,如果参数不够,那么终止运行。然后记录了打开页面的时间,请求页面之后,再纪录当前时间,二者之差就是页面加载速度。

  1. phantomjs loadspeed.js http://example.com

运行结果

  1. Loading http://example.com
  2. Loading time 11678 msec

这个时间包括JS渲染的时间,当然和网速也有关。

代码评估

利用 evaluate 方法我们可以获取网页的源代码。这个执行是“沙盒式”的,它不会去执行网页外的 JavaScript 代码。evalute 方法可以返回一个对象,然而返回值仅限于对象,不能包含函数(或闭包)

  1. var url = 'http://www.qq.com';
  2. var page = require('webpage').create();
  3. page.open(url, function(status) {
  4. var title = page.evaluate(function() {
  5. return document.title;
  6. });
  7. console.log('Page title is ' + title);
  8. phantom.exit();
  9. });

以上代码获取了腾讯的网站标题。

  1. Page title is 腾讯首页

任何来自于网页并且包括来自 evaluate() 内部代码的控制台信息,默认不会显示。

需要重写这个行为,使用 onConsoleMessage 回调函数,示例可以改写成

  1. var url = 'http://www.itcast.cn/';
  2. var page = require('webpage').create();
  3. page.onConsoleMessage = function (msg) {
  4. console.log(msg);
  5. };
  6. page.open(url, function (status) {
  7. page.evaluate(function () {
  8. console.log(document.title);
  9. });
  10. phantom.exit();
  11. });

页面自动化处理

  • DOM操作

脚本都是像在浏览器中运行的,所以标准的 JavaScript 的 DOM 操作和 CSS 选择器也是生效的。

例如下面的例子就修改了 User-Agent,然后还返回了页面中某元素的内容。

  1. var url = 'http://www.httpuseragent.org';
  2. var page = require('webpage').create();
  3. console.log('The default user agent is ' + page.settings.userAgent);
  4. page.settings.userAgent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36';
  5. page.open('http://www.httpuseragent.org', function (status) {
  6. if (status !== 'success') {
  7. console.log('Unable to access network');
  8. }
  9. else {
  10. var ua = page.evaluate(function () {
  11. return document.getElementById('myagent').innerText;
  12. });
  13. console.log(ua);
  14. }
  15. phantom.exit();
  16. });

运行结果

  1. The default user agent is Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.9.7 Safari/534.34
  2. Your Http User Agent string is: SpecialAgent

首先打印出了默认的 User-Agent,然后通过修改它,请求验证 User-Agent 的一个站点,通过选择器得到了修改后的 User-Agent。