因為項目的需要,需要使用無殼瀏覽器來抓取一些js生成的網(wǎng)頁內(nèi)容殉簸。因此學(xué)習(xí)到了phantomjs的用法蝶怔。
所謂無殼瀏覽器(Headless browser),指的是沒有圖形用戶界面的瀏覽器私痹。它具有瀏覽器的頁面解析和js代碼執(zhí)行的功能,并提供了一些API用于網(wǎng)頁的自動化控制统刮。這在自動化測試和獲取頁面Ajax異步獲取的內(nèi)容時非常有用紊遵。
下面是一些來自官方文檔的例子。
Hello world!
創(chuàng)建一個包含兩行代碼的文本文件:
console.log('Hello, world!');
phantom.exit();
保存為hello.js
,然后在命令行而不是REPL中運(yùn)行它侥蒙。
REPL是一個簡單交互的編程環(huán)境暗膜。具體可以在這里閱讀文檔。
在命令行運(yùn)行該腳本phantomjs hello.js
鞭衩,會輸出Hello, world!
学搜。
注意在腳本中調(diào)用phantom.exit()
, 否則腳本程序不會終止運(yùn)行。
頁面加載
一個頁面可以通過創(chuàng)建一個web page對象來進(jìn)行加載分析和顯示醋旦。
下面的腳本演示了最簡單的web page對象的用法恒水。它加載example.com并將頁面保存為截圖example.png
, 該截圖保存在腳本所在的目錄。
var page = require('webpage').create();
page.open('http://example.com', function(status) {
console.log("Status: " + status);
if(status === "success") {
page.render('example.png');
}
phantom.exit();
});
由于phantomjs的渲染特性饲齐,phantomjs可以用來對網(wǎng)頁內(nèi)容進(jìn)行截圖钉凌。
下面的loadspeed.js
用于測量網(wǎng)頁的加載時間。
var page = require('webpage').create(),
system = require('system'),
t, address;
if (system.args.length === 1) {
console.log('Usage: loadspeed.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 ' + system.args[1]);
console.log('Loading time ' + t + ' msec');
}
phantom.exit();
});
使用下邊的命令運(yùn)行腳本:
phantomjs loadspeed.js http://www.google.com
它會輸出類似下邊的內(nèi)容捂人。
Loading http://www.google.com Loading time 719 msec
代碼求值
為了執(zhí)行網(wǎng)頁上下文中的js代碼御雕,我們需要使用evaluate
函數(shù)矢沿。執(zhí)行代碼是運(yùn)行在一個沙盒中的,沙盒中的代碼無法訪問網(wǎng)頁上下文以外的javascript對象和變量酸纲。evaluate
可以返回一個對象捣鲸,該對象必須是一個簡單對象,不能包含函數(shù)和閉包闽坡。
下面是一個顯示網(wǎng)頁標(biāo)題的例子栽惶。
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();
});
evaluate
內(nèi)部代碼網(wǎng)頁上下文產(chǎn)生的任何控制臺信息,默認(rèn)都不會被打印出來疾嗅。我們可以使用onConsoleMessage回調(diào)函數(shù)來覆蓋默認(rèn)行為外厂。上面的例子可以重寫為:
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();
});
由于網(wǎng)頁內(nèi)部的js代碼執(zhí)行過程和在真正的網(wǎng)頁瀏覽器中并沒有什么區(qū)別,標(biāo)準(zhǔn)的DOM方法和CSS選擇器都可以在evaluate
內(nèi)部很好的使用代承。這使得phantonjs適用于執(zhí)行各種網(wǎng)頁自動化測試汁蝶。
網(wǎng)絡(luò)請求和響應(yīng)
當(dāng)一個網(wǎng)頁從遠(yuǎn)程服務(wù)器請求一個資源,請求和響應(yīng)可以通過onResourceRequested
和 onResourceReceived
回調(diào)函數(shù)進(jìn)行追蹤论悴。這在示例netlog.js中有演示掖棉。
var page = require('webpage').create();
page.onResourceRequested = function(request) {
console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function(response) {
console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(url);