2014-11-06 52 views
0

上考慮以下(工作)PhantomJS一段代碼,應該點擊whatever類的第一個元素:循環並單擊querySelectorAll清單,PhantomJS

page.evaluate(
    function() 
    { 
     var a = document.querySelector(".whatever"); 
     var e = document.createEvent('MouseEvents'); 
     e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 
     a.dispatchEvent(e); 
     waitforload = true; 
    } 
); 

我不能讓所有的循環類whatever的元素 - 問題不是循環本身,而是訪問querySelectorAll元素。

我堅持在這裏(我通過訪問第一個元素更容易調試更換循環;當然也有是兩個page.evaluate電話,因爲第二個是內環路):

var aa = page.evaluate(
    function() 
    { 
     return document.querySelectorAll(".whatever"); 
    } 
) 
//for (i=0; i<aa.length; i++) 
//{ 
page.evaluate(
    function() 
    { 
     var e = document.createEvent('MouseEvents'); 
     e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 
//  aa[i].dispatchEvent(e); 
     aa[0].dispatchEvent(e); 
     waitforload = true; 
    } 
); 
//} 

我嘗試了幾個變化,刪除var,用document.作爲變量的前綴,試圖通過aa作爲參數等。沒有任何工作(我可能錯過了正確的組合,但無論如何,我明顯缺少這裏的基礎)。

我不確定它是否與名稱空間和變量範圍(我對JS很新)有關,或者如果問題來自querySelectorAll輸出(儘管我檢查了數組的大小是否正確),因爲我遇到「ReferenceError:找不到變量」和「TypeError:'undefined'不是對象」錯誤。

任何暗示都會受到歡迎。基於

+0

是的,這與範圍/沙箱非常相關。有多種解決方案。問題是這些點擊是做什麼的?加載一個新頁面或只是改變頁面的狀態?如果是後者,你是否需要從相同的狀態開始,或者如果你只是一個接一個地點擊所有內容,那麼是否可以? – 2014-11-06 16:22:22

+0

我當然不知道。一次點擊就會加載一個包含額外信息的框該框本身隱藏了其他按鈕,因此我不知道一旦顯示該框時單擊另一個按鈕時會發生什麼。我的猜測是,它將取代或在前面的框頂部。無論如何,我的目標是讓所有這些盒子。所以一開始我會嘗試點擊一個接一個地點。 – 2014-11-06 16:55:07

回答

2

comment

One click loads a box with additional information. The box itself hides the other buttons, so I don't know what happens when one clicks on another button once the box is displayed. My guess is that it will either replace or come on top of the previous box. Anyway my goal is to get all of these boxes. So for a start I would try to click everything one after the other.

最簡單的解決辦法是檢索.whatever元素的數量,並基於該迭代,但由於它需要一些網頁交互和PhantomJS是異步的,你需要使用一些框架依次運行這些步驟。 async可用於此目的,或者您爲此腳本創建類似的內容。

function clickInPageContext(selector, index){ 
    page.evaluate(function(selector, index){ 
     index = index || 0; 
     var e = document.createEvent('MouseEvents'); 
     e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 
     var el = document.querySelectorAll(selector); 
     el[index].dispatchEvent(e); 
    }, selector, index); 
} 

var async = require("async"); // install async through npm 
var selector = ".whatever"; 
var num = page.evaluate(function(sel){ 
    return document.querySelectorAll(sel).length; 
}, selector); 
var steps = []; 
for (var i = 0; i < num; i++) { 
    // the immediately invoked function looks bad, but is necessary, 
    // because JS has function level scope and this is executed long 
    // after the loop has finished 
    steps.push((function(i){ 
     return function(complete){ 
      clickInPageContext(selector, i); 
      setTimeout(function(){ 
       clickInPageContext("someCloseButtonSelector"); // maybe also parametrized with i 
       setTimeout(function(){ 
        complete(); 
       }, 1000); // time to close 
      }, 1000); // time to open 
     }; 
    })(i)); 
} 
async.series(steps, function(){ 
    console.log("DONE"); 
    phantom.exit(); 
}); 

該測試取決於.whatever元件數保持不變的前提。注意:可以通過npm(本地)安裝異步。並且可以在PhantomJS中需要。
另外,請參閱this question,我在那裏做了類似的事情。

+0

謝謝。我用評估和記錄我需要的元素替換'clickInPageContext(「someCloseButtonSelector」)''。對於記錄來說,爲了使它工作,我必須將整段代碼(在'var selector'下面)放在我之前進行單擊和評估的地方 - 也就是說,作爲「waitFor」子句的第二個參數的函數內容。 – 2014-11-07 16:26:55

+0

是的,我希望你做出這些改變。 – 2014-11-07 16:31:16

+0

噢,感謝關於'npm'的提示,我不知道。 – 2014-11-07 16:37:47