(收藏)PhantomJS

浅陌游离 2017-04-21

http://javascript.ruanyifeng.com/tool/phantomjs.html

JavaScript标准参考教程(alpha)

开发工具

PhantomJS

GitHub

TOP

PhantomJS

来自《JavaScript标准参考教程(alpha)》,by阮一峰

目录

概述

REPL环境

webpage模块

open()

evaluate()

includeJs()

render()

viewportSize,zoomFactor

onResourceRequested

onResourceReceived

system模块

应用

过滤资源

截图

抓取图片

生成网页

参考链接

概述

有时,我们需要浏览器处理网页,但并不需要浏览,比如生成网页的截图、抓取网页数据等操作。PhantomJS的功能,就是提供一个浏览器环境的命令行接口,你可以把它看作一个“虚拟浏览器”,除了不能浏览,其他与正常浏览器一样。它的内核是WebKit引擎,不提供图形界面,只能在命令行下使用,我们可以用它完成一些特殊的用途。

PhantomJS是二进制程序,需要安装后使用。

$npminstallphantomjs-g

使用下面的命令,查看是否安装成功。

$phantomjs--version

REPL环境

phantomjs提供了一个完整的REPL环境,允许用户通过命令行与PhantomJS互动。键入phantomjs,就进入了该环境。

$phantomjs

这时会跳出一个phantom提示符,就可以输入Javascript命令了。

phantomjs>1+2

3

phantomjs>functionadd(a,b){returna+b;}

undefined

phantomjs>add(1,2)

3

按ctrl+c可以退出该环境。

下面,我们把上面的add()函数写成一个文件add.js文件。

//add.js

functionadd(a,b){returna+b;}

console.log(add(1,2));

phantom.exit();

上面的代码中,console.log()的作用是在终端窗口显示,phantom.exit()则表示退出phantomjs环境。一般来说,不管什么样的程序,exit这一行都不能少。

现在,运行该程序。

$phantomjsadd.js

终端窗口就会显示结果为3。

下面是更多的例子。

phantomjs>phantom.version

{

"major":1,

"minor":5,

"patch":0

}

phantomjs>console.log("phantomisawesome")

phantomisawesome

phantomjs>window.navigator

{

"cookieEnabled":true,

"language":"en-GB",

"productSub":"20030107",

"product":"Gecko",

//...

}

webpage模块

webpage模块是PhantomJS的核心模块,用于网页操作。

varwebPage=require('webpage');

varpage=webPage.create();

上面代码表示加载PhantomJS的webpage模块,并创建一个实例。

下面是webpage实例的属性和方法介绍。

open()

open方法用于打开具体的网页。

varpage=require('webpage').create();

page.open('http://slashdot.org',function(s){

console.log(s);

phantom.exit();

});

上面代码中,open()方法,用于打开具体的网页。它接受两个参数。第一个参数是网页的网址,这里打开的是著名新闻网站Slashdot,第二个参数是回调函数,网页打开后该函数将会运行,它的参数是一个表示状态的字符串,如果打开成功就是success,否则就是fail。

注意,只要接收到服务器返回的结果,PhantomJS就会报告网页打开成功,而不管服务器是否返回404或500错误。

open方法默认使用GET方法,与服务器通信,但是也可以使用其他方法。

varwebPage=require('webpage');

varpage=webPage.create();

varpostBody='user=username&password=password';

page.open('http://www.google.com/','POST',postBody,function(status){

console.log('Status:'+status);

//Dootherthingshere...

});

上面代码中,使用POST方法向服务器发送数据。open方法的第二个参数用来指定HTTP方法,第三个参数用来指定该方法所要使用的数据。

open方法还允许提供配置对象,对HTTP请求进行更详细的配置。

varwebPage=require('webpage');

varpage=webPage.create();

varsettings={

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);

//Dootherthingshere...

});

evaluate()

evaluate方法用于打开网页以后,在页面中执行JavaScript代码。

varpage=require('webpage').create();

page.open(url,function(status){

vartitle=page.evaluate(function(){

returndocument.title;

});

console.log('Pagetitleis'+title);

phantom.exit();

});

网页内部的console语句,以及evaluate方法内部的console语句,默认不会显示在命令行。这时可以采用onConsoleMessage回调函数,上面的例子可以改写如下。

varpage=require('webpage').create();

page.onConsoleMessage=function(msg){

console.log('Pagetitleis'+msg);

};

page.open(url,function(status){

page.evaluate(function(){

console.log(document.title);

});

phantom.exit();

});

上面代码中,evaluate方法内部有console语句,默认不会输出在命令行。这时,可以用onConsoleMessage方法监听这个事件,进行处理。

includeJs()

includeJs方法用于页面加载外部脚本,加载结束后就调用指定的回调函数。

varpage=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()

render方法用于将网页保存成图片,参数就是指定的文件名。该方法根据后缀名,将网页保存成不同的格式,目前支持PNG、GIF、JPEG和PDF。

varwebPage=require('webpage');

varpage=webPage.create();

page.viewportSize={width:1920,height:1080};

page.open("http://www.google.com",functionstart(status){

page.render('google_home.jpeg',{format:'jpeg',quality:'100'});

phantom.exit();

});

该方法还可以接受一个配置对象,format字段用于指定图片格式,quality字段用于指定图片质量,最小为0,最大为100。

viewportSize,zoomFactor

viewportSize属性指定浏览器视口的大小,即网页加载的初始浏览器窗口大小。

varwebPage=require('webpage');

varpage=webPage.create();

page.viewportSize={

width:480,

height:800

};

viewportSize的Height字段必须指定,不可省略。

zoomFactor属性用来指定渲染时(render方法和renderBase64方法)页面的放大系数,默认是1(即100%)。

varwebPage=require('webpage');

varpage=webPage.create();

page.zoomFactor=0.25;

page.render('capture.png');

onResourceRequested

onResourceRequested属性用来指定一个回调函数,当页面请求一个资源时,会触发这个回调函数。它的第一个参数是HTTP请求的元数据对象,第二个参数是发出的网络请求对象。

HTTP请求包括以下字段。

id:所请求资源的编号

method:使用的HTTP方法

url:所请求的资源URL

time:一个包含请求时间的Date对象

headers:HTTP头信息数组

网络请求对象包含以下方法。

abort():终止当前的网络请求,这会导致调用onResourceError回调函数。

changeUrl(newUrl):改变当前网络请求的URL。

setHeader(key,value):设置HTTP头信息。

varwebPage=require('webpage');

varpage=webPage.create();

page.onResourceRequested=function(requestData,networkRequest){

console.log('Request(#'+requestData.id+'):'+JSON.stringify(requestData));

};

onResourceReceived

onResourceReceived属性用于指定一个回调函数,当网页收到所请求的资源时,就会执行该回调函数。它的参数就是服务器发来的HTTP回应的元数据对象,包括以下字段。

id:所请求的资源编号

url:所请求的资源的URLr-time:包含HTTP回应时间的Date对象

headers:HTTP头信息数组

bodySize:解压缩后的收到的内容大小

contentType:接到的内容种类

redirectURL:重定向URL(如果有的话)

stage:对于多数据块的HTTP回应,头一个数据块为start,最后一个数据块为end。

status:HTTP状态码,成功时为200。

statusText:HTTP状态信息,比如OK。

如果HTTP回应非常大,分成多个数据块发送,onResourceReceived会在收到每个数据块时触发回调函数。

varwebPage=require('webpage');

varpage=webPage.create();

page.onResourceReceived=function(response){

console.log('Response(#'+response.id+',stage"'+response.stage+'"):'+JSON.stringify(response));

};

system模块

system模块可以加载操作系统变量,system.args就是参数数组。

varpage=require('webpage').create(),

system=require('system'),

t,address;

//如果命令行没有给出网址

if(system.args.length===1){

console.log('Usage:page.js<someURL>');

phantom.exit();

}

t=Date.now();

address=system.args[1];

page.open(address,function(status){

if(status!=='success'){

console.log('FAILtoloadtheaddress');

}else{

t=Date.now()-t;

console.log('Loadingtime'+t+'ms');

}

phantom.exit();

});

使用方法如下:

$phantomjspage.jshttp://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方法中断连接。

截图

最简单的生成网页截图的方法如下。

varpage=require('webpage').create();

page.open('http://google.com',function(){

page.render('google.png');

phantom.exit();

});

page对象代表一个网页实例;open方法表示打开某个网址,它的第一个参数是目标网址,第二个参数是网页载入成功后,运行的回调函数;render方法则是渲染页面,然后以图片格式输出,该方法的参数就是输出的图片文件名。

除了简单截图以外,还可以设置各种截图参数。

varpage=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

varpage=require('webpage').create();

page.settings.userAgent='WebKit/534.46Mobile/9A405Safari/7534.48.3';

page.settings.viewportSize={width:400,height:600};

page.open('http://slashdot.org',function(status){

if(status!=='success'){

console.log('Unabletoload!');

phantom.exit();

}else{

vartitle=page.evaluate(function(){

varposts=document.getElementsByClassName("article");

posts[0].style.backgroundColor="#FFF";

returndocument.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);

}

});

上面代码中的几个属性和方法解释如下:

settings.userAgent:指定HTTP请求的userAgent头信息,上面例子是手机浏览器的userAgent。

settings.viewportSize:指定浏览器窗口的大小,这里是400x600。

evaluate():用来在网页上运行Javascript代码。在这里,我们抓取第一条新闻,然后修改背景颜色,并返回该条新闻的标题。

clipRect:用来指定网页截图的大小,这里的截图左上角从网页的(0.0)坐标开始,宽600像素,高700像素。如果不指定这个值,就表示对整张网页截图。

render():根据clipRect的范围,在当前目录下生成以第一条新闻的名字命名的截图。

抓取图片

使用官方网站提供的rasterize.js,可以抓取网络上的图片,将起保存在本地。

phantomjsrasterize.jshttp://ariya.github.com/svg/tiger.svgtiger.png

使用rasterize.js,还可以将网页保存为pdf文件。

phantomjsrasterize.js'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes'jakarta.pdf

生成网页

phantomjs可以生成网页,使用content方法指定网页的HTML代码。

varpage=require('webpage').create();

page.viewportSize={width:400,height:400};

page.content='<html><body><canvasid="surface"></canvas></body></html>';

phantom.exit();

官方网站有一个例子,通过创造svg图片,然后截图保存成png文件。

相关推荐