PhantomJs的用法(二)——常用API

1、命令行界面与REPL环境

假设构建了PhantomJS 并将其可执行文件放在PATH中的某个位置,可以按如下方式调用它:

phantomjs [options] example.js [arg1 [arg2 [...]]]

脚本代码将像在具有空页面的Web浏览器中运行一样执行。由于PhantomJS是无头的,因此屏幕上不会显示任何可见的内容。如果在没有任何参数的情况下调用PhantomJS,它将进入交互模式(REPL),在这个环境中允许用户通过命令行与PhantomJS互动。键入phantomjs,就进入了该环境。

进入REPL环境.png
这时会跳出一个phantom提示符,就可以输入Javascript命令了。
输入JavaScript命令.png

Ctrl + C即可退出该环境。
也可将上面的sum函数写成一个sum.js文件:

function sum (a, b) {
    return a+b;
}

console.log(sum(2,3));  // 在终端窗口显示

phantom.exit();  // 退出phantomjs环境
  • 通常情况下,不管什么样的程序,phantom.exit();这一行都不能少。
  • 为防止输出中文时出现乱码,可设置网页编码格式phantom.outputEncoding="gbk";

2、PhantomJs 常用内置对象

  • webpage模块

webpage模块是PhantomJs的核心模块,用于网页操作,获取操作DOM或者web网页的对象,通过它可以打开网页、接收网页内容、request、response参数等。提供了一套可以访问和操作web文档的核心方法,包括操作DOM、事件捕获、用户事件模拟等等。

var webPage = require('webpage');  // 加载PhantomJs的webpage模块
var page = webPage.create();  // 创建一个实例
  • fs模块

获取文件系统对象,通过它可以操作操作系统的文件操作,包括read、write、move、copy、delete等

var fs = require('fs');
  • system模块

system模块可以获得系统操作对象,包括命令行参数、phantomjs系统设置等信息

var system = require('system');

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

3、PhantomJs常用API

由于webpage是PhantomJs的核心模块,所以PhantomJs常用的基本都是webpage的API,下面介绍常用的webpage实例的属性与方法。

(1)常用方法

  • open()

该方法用于打开具体的网页,该方法接受四种参数形式:

// url:将要被打开的网页的网址  
// callback:网页被彻底打开完毕是的回调函数
// method:用来指定HTPP的方法,默认为GET方法,也可指定为POST方法等
// data:用来指定该方法所要使用的数据
// settings:HTTP的配置对象
open(url, callback) {}

open(url, method, callback) {}

open(url, method, data, callback) {}

open(url, settings, callback) {}

打开baidu.com并返回successfail

var page = require('webpage').create();
page.open('https://www.baidu.com/', function (status) {
    console.log(status);  // 若打开成功则打印出success,否则输出fail
    phantom.exit();
});

注意,只要接收到服务器返回的结果,PhantomJS就会报告网页打开成功,而不管服务器是否返回404或500错误。
open函数还可用于通过GET以外的方法请求URL。此语法还包括指定要随请求一起发送的数据。

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

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

evaluate方法用于打开网页以后,在页面中执行JavaScript代码,在所加载的web page内部执行该函数,像翻页、点击、滑动等,均可在此中执行,在网页内部无法访问phantom对象。

evaluate(function, arg1, arg2, ...)

获取网页的标题

var page = require('webpage').create();
phantom.outputEncoding="gbk"; // 为防止输出中文时出现乱码,可设置输出编码格式
page.open('https://www.baidu.com/', function () {
    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('https://www.baidu.com/', function () {
    page.evaluate(function(){
        console.log(document.title);
    });
    
    phantom.exit();
});
  • includeJs()

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

var page = require('webpage').create();

page.open('https://www.baidu.com/', function () {
    page.includeJs('https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js', function () {
        page.evaluate(function () {
            $('.button').click();
        });
        phantom.exit();
    });
});

上面的例子在页面中注入jQuery脚本,然后点击所有的按钮。需要注意的是,由于是异步加载,所以phantom.exit()语句要放在page.includeJs()方法的回调函数之中,否则页面会过早退出。

  • render()

render(filename [, {format, quality}]) {}

render方法用于将网页保存成图片,参数就是指定的文件名。该方法根据后缀名,将网页保存成不同的格式,支持的格式如下:

  • PDF
  • PNG
  • JPEG
  • BMP
  • PPM
  • GIF的支持取决于使用的Qt值
var page = require('webpage').create();

page.viewportSize = { width: 1920, height: 1080 };
page.open("https://www.baidu.com", function start(status) {
  page.render('baidu_home.jpeg', {format: 'jpeg', quality: '100'});
  phantom.exit();
});

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

(2)常用属性

  • viewportSize,zoomFactor

viewportSize属性指定浏览器视口的大小,即网页加载的初始浏览器窗口大小。因为PhantomJS是无头的(没有显示任何内容),所以viewportSize有效地模拟了传统浏览器中窗口的大小。viewportSizeHeight字段必须指定,不可省略。

var webPage = require('webpage');
var page = webPage.create();

page.viewportSize = {
  width: 480,
  height: 800
};

zoomFactor属性用来指定渲染时(render方法和renderBase64方法)页面的放大系数,默认是1(即100%)。如下是使用25%缩放创建缩略图预览:

var webPage = require('webpage');
var page = webPage.create();

page.zoomFactor = 0.25;
page.render('capture.png');
  • onLoadStarted

page.open()调用时,会首先执行该回调函数,也就是页面开始加载时调用此回调,没有参数传递给回调,在此可以预置一些参数或函数,用于后边的回调函数中。

var webPage = require('webpage');
var page = webPage.create();

page.onLoadStarted = function() {
  var currentUrl = page.evaluate(function() {
    return window.location.href;
  });
  console.log('Current page ' + currentUrl + ' will be gone...');
};
  • onResourceRequested

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

  • id:所请求资源的编号
  • method:使用的HTTP方法
  • url:所请求的资源 URL
  • time:一个包含请求时间的Date对象
  • headers:HTTP头信息数组

networkRequest对象包含以下方法:

  • bort():终止当前的网络请求,这会导致调用onResourceError回调函数。
  • changeUrl(newUrl):改变当前网络请求的URL。
  • setHeader(key, value):设置HTTP头信息。
var webPage = require('webpage');
var page = webPage.create();

page.onResourceRequested = function(requestData, networkRequest) {
  var match = requestData.url.match(/wordfamily.js/g);
  if (match != null) {
    console.log('Request (#' + requestData.id + '): ' + JSON.stringify(requestData));
    networkRequest.changeUrl('newWordFamily.js'); 
  }
};

通过调用networkRequest.changeUrl(newUrl),我们可以将请求URL更改为新URL。这是提供远程资源替代实现的唯一方法。

  • onResourceReceived

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

  • id:所请求的资源编号
  • url:所请求的资源的URL r- time:包含HTTP回应时间的Date对象
  • headers:HTTP头信息数组
  • bodySize:解压缩后的收到的内容大小
  • contentType:接到的内容种类
  • redirectURL:重定向URL(如果有的话)
  • stage:对于多数据块的HTTP回应,头一个数据块为start,最后一个数据块为end。
  • status:HTTP状态码,成功时为200。
  • statusText:HTTP状态信息,比如OK。

如果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));
};
  • onResourceError

当网页无法加载资源或加载资源时出现了各种失败时,将调用此回调。回调的唯一参数是resourceError元数据对象,该对象包含以下属性:

  • id :请求的编号
  • url :资源网址
  • errorCode :错误代码
  • errorString :错误描述
var webPage = require('webpage');
var page = webPage.create();

page.onResourceError = function(resourceError) {
  console.log('Unable to load resource (#' + resourceError.id + 'URL:' + resourceError.url + ')');
  console.log('Error code: ' + resourceError.errorCode + '. Description: ' + resourceError.errorString);
};
  • 其他

  • onConsoleMessage :在执行web网页时,打印一些输出信息到控制台,则可以在此回调显示。
page.onConsoleMessage = function (msg) {}
  • onAlertphantomjs是没有界面的,所以对alert也是无法直接弹出的,故phantomjs以该函数回调在page执行过程中的alert事件。
page.onAlert = function(msg) {}
  • onError:当page.open中的url,它自己(不包括所引起的其它的加载资源)出现了异常,如404、no route to web site等,都会在此回调显示。
page.onError = function(msg, trace) {}
  • onUrlChanged:当page.open打开的url或是该url在打开过程中基于该URL进行了跳转,则可在此函数中回调。
page.onUrlChanged = function(targetUrl) {}
  • onLoadFinished:当page.open的目标URL被真正打开后,会在调用open的回调函数前调用该函数,在此可以进行内部的翻页等操作。
page.onLoadFinished = function(status){} 

更多详情可参考 PhantomJs官网API

PhantomJs系列文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269