来自《JavaScript 标准参考教程(alpha)》,by 阮一峰javascript
重要说明:本教程已经搬迁,此处再也不维护,请访问新网址:wangdoc.com/javascript。css
有时,咱们须要浏览器处理网页,但并不须要浏览,好比生成网页的截图、抓取网页数据等操做。PhantomJS的功能,就是提供一个浏览器环境的命令行接口,你能够把它看做一个“虚拟浏览器”,除了不能浏览,其余与正常浏览器同样。它的内核是WebKit引擎,不提供图形界面,只能在命令行下使用,咱们能够用它完成一些特殊的用途。html
PhantomJS是二进制程序,须要安装后使用。java
$ npm install phantomjs -g
使用下面的命令,查看是否安装成功。jquery
$ phantomjs --version
phantomjs提供了一个完整的REPL环境,容许用户经过命令行与PhantomJS互动。键入phantomjs,就进入了该环境。git
$ phantomjs
这时会跳出一个phantom提示符,就能够输入Javascript命令了。github
phantomjs> 1+2 3 phantomjs> function add(a,b) { return a+b; } undefined phantomjs> add(1,2) 3
按ctrl+c能够退出该环境。web
下面,咱们把上面的add()函数写成一个文件add.js文件。ajax
// add.js function add(a,b){ return a+b; } console.log(add(1,2)); phantom.exit();
上面的代码中,console.log()的做用是在终端窗口显示,phantom.exit()则表示退出phantomjs环境。通常来讲,无论什么样的程序,exit这一行都不能少。
如今,运行该程序。
$ phantomjs add.js
终端窗口就会显示结果为3。
下面是更多的例子。
phantomjs> phantom.version { "major": 1, "minor": 5, "patch": 0 } phantomjs> console.log("phantom is awesome") phantom is awesome phantomjs> window.navigator { "cookieEnabled": true, "language": "en-GB", "productSub": "20030107", "product": "Gecko", // ... }
webpage模块是PhantomJS的核心模块,用于网页操做。
var webPage = require('webpage'); var page = webPage.create();
上面代码表示加载PhantomJS的webpage模块,并建立一个实例。
下面是webpage实例的属性和方法介绍。
open方法用于打开具体的网页。
var page = require('webpage').create(); page.open('http://slashdot.org', function (s) { console.log(s); phantom.exit(); });
上面代码中,open()方法,用于打开具体的网页。它接受两个参数。第一个参数是网页的网址,这里打开的是著名新闻网站Slashdot,第二个参数是回调函数,网页打开后该函数将会运行,它的参数是一个表示状态的字符串,若是打开成功就是success,不然就是fail。
注意,只要接收到服务器返回的结果,PhantomJS就会报告网页打开成功,而无论服务器是否返回404或500错误。
open方法默认使用GET方法,与服务器通讯,可是也可使用其余方法。
var webPage = require('webpage'); var page = webPage.create(); var postBody = 'user=username&password=password'; page.open('http://www.google.com/', 'POST', postBody, function(status) { console.log('Status: ' + status); // Do other things here... });
上面代码中,使用POST方法向服务器发送数据。open方法的第二个参数用来指定HTTP方法,第三个参数用来指定该方法所要使用的数据。
open方法还容许提供配置对象,对HTTP请求进行更详细的配置。
var webPage = require('webpage'); var page = webPage.create(); var settings = { operation: "POST", encoding: "utf8", headers: { "Content-Type": "application/json" }, data: JSON.stringify({ some: "data", another: ["custom", "data"] }) }; page.open('http://your.custom.api', settings, function(status) { console.log('Status: ' + status); // Do other things here... });
evaluate方法用于打开网页之后,在页面中执行JavaScript代码。
var page = require('webpage').create(); page.open(url, function(status) { var title = page.evaluate(function() { return document.title; }); console.log('Page title is ' + title); phantom.exit(); });
网页内部的console语句,以及evaluate方法内部的console语句,默认不会显示在命令行。这时能够采用onConsoleMessage回调函数,上面的例子能够改写以下。
var page = require('webpage').create(); page.onConsoleMessage = function(msg) { console.log('Page title is ' + msg); }; page.open(url, function(status) { page.evaluate(function() { console.log(document.title); }); phantom.exit(); });
上面代码中,evaluate方法内部有console语句,默认不会输出在命令行。这时,能够用onConsoleMessage方法监听这个事件,进行处理。
includeJs方法用于页面加载外部脚本,加载结束后就调用指定的回调函数。
var page = require('webpage').create(); page.open('http://www.sample.com', function() { page.includeJs("http://path/to/jquery.min.js", function() { page.evaluate(function() { $("button").click(); }); phantom.exit() }); });
上面的例子在页面中注入jQuery脚本,而后点击全部的按钮。须要注意的是,因为是异步加载,因此phantom.exit()
语句要放在page.includeJs()
方法的回调函数之中,不然页面会过早退出。
render方法用于将网页保存成图片,参数就是指定的文件名。该方法根据后缀名,将网页保存成不一样的格式,目前支持PNG、GIF、JPEG和PDF。
var webPage = require('webpage'); var page = webPage.create(); page.viewportSize = { width: 1920, height: 1080 }; page.open("http://www.google.com", function start(status) { page.render('google_home.jpeg', {format: 'jpeg', quality: '100'}); phantom.exit(); });
该方法还能够接受一个配置对象,format字段用于指定图片格式,quality字段用于指定图片质量,最小为0,最大为100。
viewportSize属性指定浏览器视口的大小,即网页加载的初始浏览器窗口大小。
var webPage = require('webpage'); var page = webPage.create(); page.viewportSize = { width: 480, height: 800 };
viewportSize的Height字段必须指定,不可省略。
zoomFactor属性用来指定渲染时(render方法和renderBase64方法)页面的放大系数,默认是1(即100%)。
var webPage = require('webpage'); var page = webPage.create(); page.zoomFactor = 0.25; page.render('capture.png');
onResourceRequested属性用来指定一个回调函数,当页面请求一个资源时,会触发这个回调函数。它的第一个参数是HTTP请求的元数据对象,第二个参数是发出的网络请求对象。
HTTP请求包括如下字段。
网络请求对象包含如下方法。
var webPage = require('webpage'); var page = webPage.create(); page.onResourceRequested = function(requestData, networkRequest) { console.log('Request (#' + requestData.id + '): ' + JSON.stringify(requestData)); };
onResourceReceived属性用于指定一个回调函数,当网页收到所请求的资源时,就会执行该回调函数。它的参数就是服务器发来的HTTP回应的元数据对象,包括如下字段。
若是HTTP回应很是大,分红多个数据块发送,onResourceReceived会在收到每一个数据块时触发回调函数。
var webPage = require('webpage'); var page = webPage.create(); page.onResourceReceived = function(response) { console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + JSON.stringify(response)); };
system模块能够加载操做系统变量,system.args就是参数数组。
var page = require('webpage').create(), system = require('system'), t, address; // 若是命令行没有给出网址 if (system.args.length === 1) { console.log('Usage: page.js <some URL>'); phantom.exit(); } t = Date.now(); address = system.args[1]; page.open(address, function (status) { if (status !== 'success') { console.log('FAIL to load the address'); } else { t = Date.now() - t; console.log('Loading time ' + t + ' ms'); } phantom.exit(); });
使用方法以下:
$ phantomjs page.js http://www.google.com
Phantomjs能够实现多种应用。
处理页面的时候,有时不但愿加载某些特定资源。这时,能够对URL进行匹配,一旦符合规则,就中断对资源的链接。
page.onResourceRequested = function(requestData, request) { if ((/http:\/\/.+?\.css$/gi).test(requestData['url'])) { console.log('Skipping', requestData['url']); request.abort(); } };
上面代码一旦发现加载的资源是CSS文件,就会使用request.abort
方法中断链接。
最简单的生成网页截图的方法以下。
var page = require('webpage').create(); page.open('http://google.com', function () { page.render('google.png'); phantom.exit(); });
page对象表明一个网页实例;open方法表示打开某个网址,它的第一个参数是目标网址,第二个参数是网页载入成功后,运行的回调函数;render方法则是渲染页面,而后以图片格式输出,该方法的参数就是输出的图片文件名。
除了简单截图之外,还能够设置各类截图参数。
var page = require('webpage').create(); page.open('http://google.com', function () { page.zoomFactor = 0.25; console.log(page.renderBase64()); phantom.exit(); });
zoomFactor表示将截图缩小至原图的25%大小;renderBase64方法则是表示将截图(PNG格式)编码成Base64格式的字符串输出。
下面的例子则是使用了更多参数。
// page.js var page = require('webpage').create(); page.settings.userAgent = 'WebKit/534.46 Mobile/9A405 Safari/7534.48.3'; page.settings.viewportSize = { width: 400, height: 600 }; page.open('http://slashdot.org', function (status) { if (status !== 'success') { console.log('Unable to load!'); phantom.exit(); } else { var title = page.evaluate(function () { var posts = document.getElementsByClassName("article"); posts[0].style.backgroundColor = "#FFF"; return document.title; }); window.setTimeout(function () { page.clipRect = { top: 0, left: 0, width: 600, height: 700 }; page.render(title + "1.png"); page.clipRect = { left: 0, top: 600, width: 400, height: 600 }; page.render(title + '2.png'); phantom.exit(); }, 1000); } });
上面代码中的几个属性和方法解释以下:
使用官方网站提供的rasterize.js,能够抓取网络上的图片,将其保存在本地。
phantomjs rasterize.js http://ariya.github.com/svg/tiger.svg tiger.png
使用rasterize.js,还能够将网页保存为pdf文件。
phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf
phantomjs能够生成网页,使用content方法指定网页的HTML代码。
var page = require('webpage').create(); page.viewportSize = { width: 400, height : 400 }; page.content = '<html><body><canvas id="surface"></canvas></body></html>'; phantom.exit();
官方网站有一个例子,经过创造svg图片,而后截图保存成png文件。