phamtomjs能否得到js運行後的代碼並輸出到文檔?
如題
比如AJAX網站下,只有js運行過才顯示的信息能否在phamtomjs里顯示並 輸出?用了Open方法,但是得到的中文在CMD中是亂碼。另一個問題是如何讓console里的內容保存下來呢?
知乎上居然有人問PhantomJS的問題,必須怒答。
可以的。不過要得到所有Ajax完成後的頁面,需要做一些特別的判定。
PhantomJS的渲染引擎就是QtWebkit,JS引擎是JavascriptCore(不是V8),所以大致上可以當作一個沒有GUI的Safari。
所以PhantomJs載入一個網頁,基本跟Safari一樣了,自然所有Javascript都會被解析執行的(不管 這些代碼是否會修改DOM)
要想測試的話,可以用PhantomJS截圖的API,找一個Ajax請求很多的頁面,每隔200毫秒截一張圖,就能看到具體頁面loading的過程了。
一般在無Ajax網頁,可以直接調用PhantomJS載入頁面的callback來獲取結果。但是在有Ajax的情況下,這個Callback被調用的時候,後台Ajax命令可能還在執行中(或者還沒發出去),所以需要手動添加一些代碼(比如setTimeout(2000)一類的),來等待所有Ajax命令執行結束。
具體的做法是:
1. 最簡單的
假設你使用open(url, callback)這個函數打開頁面。這個函數callback的是在頁面DOM Loaded後不久就觸發了。但是這個時候Ajax的請求不一定執行完畢。所以要在open(url, callback)這裡的callback裡面再加上一個setTimeout來等待Ajax執行完畢。但是這個做法缺陷是,我並不知道具體要setTimeout多久才能保證ajax執行完畢。
2. 稍微複雜點,解決方案。
PhantomJS有個兩個callback API是page.onResourceRequested //在頁面每個request發出的時候被觸發
page.onResourceReceived //在頁面每個response收到的時候被觸發
在這兩個callback裡面記錄下每個request的id,和每個response的id,並在open(url, callback)的callback被調用的時候,檢查是否每個request都有對應的response。如果不是的話,說明有ajax request被發了出去,但是並沒有收到,因此繼續調用setTimeout來等待。直到所有request都有對應的response。
2. 最麻煩的
直接改掉PhantomJS的源碼,讓他在N秒內沒有新的request發出後,再觸發open(url, callback)裡面的callback。可以參考我的改動https://github.com/ye11ow/phantomjs,不過我是改得Ghostdriver, 而不是PhantomJS本身用 setTimeout 也有問題,鬼知道要等多久的,不過有一種方法,也就是獲取 document.readyState ,判斷是否 complete,知道到達預期。
function onComplete() {
setTimeout(function () {
var readyState = page.evaluate(function () {
return document.readyState;
});
if (readyState === "complete") {
parse();
}
else {
onComplete();
}
}, 1000);
}
亂碼的話,在執行腳本的頭部加上phantom.outputEncoding = 『gb2312』;試試
如何判斷Ajax執行完畢? Ajax執行完畢後,頁面會有一些特徵(Flag),程序中加個sleep,循環檢測(直到自認為的超時),一旦發現Flag就認為Ajax執行完畢,可以讀取頁面源碼進而獲取Ajax的執行結果了。
推薦閱讀:
TAG:前端開發 | JavaScript | Ajax | PhantomJs |