2012-10-03 16 views
21

我正在將PhantomJS無頭瀏覽器集成到我的項目(當前使用版本1.6)。在大多數情況下,它在完成我需要完成的任務方面做得很好。然而,WebPage.open()調用方式的異步特性以及需要在某個時候調用phantom.exit(),這使得處理客戶端重定向變得非常棘手,因爲無法預測他們將要去的地方去。如何僅在客戶端重定向發生後才結束PhantomJS腳本

我所追求的是一種只有在任何元刷新(導致不同的頁面)之後調用phantom.exit()並且JavaScript重定向綁定到onload事件等事件的方式。我可以看到爲什麼這是一個問題,因爲從理論上說,客戶端重定向可能會在頁面加載後的任意數秒內發生,並且我不能簡單地要求只有當沒有更多重定向要去時才能退出發生。現在,我能想到的最佳解決方案是:a)手動檢測頁面上的元刷新元素的存在並自行處理這些元素; b)使用setInterval()來允許一些相當長的時間(比如1-調用phantom.exit()之前經過1.5秒)。它基本上是這樣的:

var page = require('webpage').create(); 
var visitComplete = false; 
var url = "http://some.url"; 
var pageOpenedTime; 
setInterval(function() { 
    if (visitcomplete && typeof pageOpenedTime != 'undefined' && 
     new Date() - pageOpenedTime >= 1500) 
    { 
     phantom.exit(); 
    } 
), 1000); 
page.open(url, function() { 
    pageOpenedTime = new Date(); 
    if (!hasMetaRefresh(page)) { 
     visitComplete = true; 
    } 
}); 

function hasMetaRefresh(page) { 
    // Query the DOM here to detect meta refresh elements 
} 

有什麼更好的想法?

編輯:我應該提到,我的第一個想法是,可能會有一個PhantomJS事件在與初始頁面加載相關的JavaScript已執行時被觸發,但onLoadFinished回調似乎在執行任何in-頁面JavaScript,包括onload事件。我還做了一些關於可能需要等待的時間間隔的測試,並且雖然1000毫秒足夠長,以便在一個小測試頁中執行JavaScript重定向(通過body onload事件),但100 ms還不夠長。

+0

我在我的項目中使用了相同的方法,即通話之間增加了一點暫停。恐怕這是唯一的選擇(現在)。 –

回答

0

我有這個想法使用嘲笑定時器爲此目的。假設我們在頁面中包含"a mocked timer"。這樣,您可以快速前進以避免js空閒時間。請參閱GitHub頁面上的示例。

這只是一種使事情更快發生的方法,但正如您所期望的那樣,無法確定將來是否會觸發重定向事件。

8

加載正在使用Optimizely的頁面時出現同樣的問題,並且變體是location.href重定向。

我現在在「renderPage」函數中使用onNavigationRequest回調。那些優化重定向不再阻塞,我不需要任意超時。

var webpage = require('webpage'); 
var page = null; 

var renderPage = function (myurl) { 
    page = webpage.create(); 

    page.onNavigationRequested = function(url, type, willNavigate, main) { 
     if (main && url!=myurl && url.replace(/\/$/,"")!=myurl&& (type=="Other" || type=="Undefined")) { 
     // main = navigation in main frame; type = not by click/submit etc 

      log("\tfollowing "+myurl+" redirect to "+url) 
      myurl = url; 
      page.close(); 
      renderPage(url); // rerun this function wit the new URL 
     } 
    }; // on Nav req 

    page.open(myurl, function(status) { 
     if (status==="success") { 
      page.render("screenshot.jpg"); 
     } else { 
      page.close(); 
     } 
    }); // page open 
} // render page 


renderPage("http://some.domain.com"); 

看到文檔:http://phantomjs.org/api/webpage/handler/on-navigation-requested.html

+0

這將適用於標題重定向,js重定向和用戶操作的權利? – CMCDragonkai

+0

@CMCDragonkai:根據我的用法,這適用於URL中的任何更改 - 因此我們收到302 - >瀏覽器向它發出新請求 - >導航更改 如果通過JavaScript執行location.href, Useractions(即模擬的鼠標點擊和表單提交等)的處理方式不同:帶有更改的「type」值(類型:可能的值包括:'Undefined','LinkClicked','FormSubmitted','BackOrForward','Reload','FormResubmitted' ,'其他') – ProfessionalHack

0

我已經簽出各種實例爲phantomjs的重定向處理:倒黴。

暫時沒有通用的修復方法。如果你修補一些腳本 as suggested here,它會在其他情況下失敗,例如,旁邊使用location.href,使用JavaScript重定向。我還沒有測試身體。在這裏和那裏補幾筆錢後,我放棄了。

我只是使用「重」硒觸發的火狐來解決我的問題。如果你需要加載很多頁面,而不是重新啓動Firefox,只需使用webdriver.delete_all_cookies()清理一些catch。它給了我可靠的結果(我需要做屏幕截圖,下載html,得到最終的網址,以及更多)與phantomjs相比。

相關問題