因為項目的需要,需要使用無殼瀏覽器來抓取一些js生成的網頁內容。因此學習到了phantomjs的用法。
所謂無殼瀏覽器(Headless browser),指的是沒有圖形用戶界面的瀏覽器。它具有瀏覽器的頁面解析和js代碼執行的功能,并提供了一些API用于網頁的自動化控制。這在自動化測試和獲取頁面Ajax異步獲取的內容時非常有用。
下面是一些來自官方文檔的例子。
Hello world!
創建一個包含兩行代碼的文本文件:
console.log('Hello, world!');
phantom.exit();
保存為hello.js
,然后在命令行而不是REPL中運行它。
REPL是一個簡單交互的編程環境。具體可以在這里閱讀文檔。
在命令行運行該腳本phantomjs hello.js
,會輸出Hello, world!
。
注意在腳本中調用phantom.exit()
, 否則腳本程序不會終止運行。
頁面加載
一個頁面可以通過創建一個web page對象來進行加載分析和顯示。
下面的腳本演示了最簡單的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可以用來對網頁內容進行截圖。
下面的loadspeed.js
用于測量網頁的加載時間。
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();
});
使用下邊的命令運行腳本:
phantomjs loadspeed.js http://www.google.com
它會輸出類似下邊的內容。
Loading http://www.google.com Loading time 719 msec
代碼求值
為了執行網頁上下文中的js代碼,我們需要使用evaluate
函數。執行代碼是運行在一個沙盒中的,沙盒中的代碼無法訪問網頁上下文以外的javascript對象和變量。evaluate
可以返回一個對象,該對象必須是一個簡單對象,不能包含函數和閉包。
下面是一個顯示網頁標題的例子。
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
內部代碼網頁上下文產生的任何控制臺信息,默認都不會被打印出來。我們可以使用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();
});
由于網頁內部的js代碼執行過程和在真正的網頁瀏覽器中并沒有什么區別,標準的DOM方法和CSS選擇器都可以在evaluate
內部很好的使用。這使得phantonjs適用于執行各種網頁自動化測試。
網絡請求和響應
當一個網頁從遠程服務器請求一個資源,請求和響應可以通過onResourceRequested
和 onResourceReceived
回調函數進行追蹤。這在示例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);