2017-06-03 146 views
1

我使用CasperJS運行以下腳本,在通過陣列約三分之一的時間後,它開始用盡交換空間,機器變得非常慢。我在這裏做錯了什麼?CasperJS內存不足

searchPages是54個數字的數組,對應於搜索頁面的URL值。

casper.each(searchPages,function(casper,index){ 
    loadSearch(casper,index); 
}); 


function loadSearch(casper,index){ 
    var currentTime = new Date(); 
    var month = currentTime.getMonth() + 2; 
    var day = currentTime.getDate(); 
    var year = currentTime.getFullYear(); 
    var dateStart = month + "/" + day + "/" + year; 
    month = currentTime.getMonth() + 3; 
    var dateEnd = month + "/" + day + "/" + year; 

    casper.thenOpen(url,function(){ 
     var myfile = "data-"+year + "-" + month + "-" + day+".html"; 
     this.evaluate(function(j) { 
      document.querySelector('select[name="searchParameters.localeId"]').selectedIndex = j; 
     },index); 
     this.evaluate(function(start) { 
      $("#leaveDate").val(start); 
     },dateStart); 
     this.evaluate(function(end) { 
      $("#returnDate").val(end); 
     },dateEnd); 
     this.evaluate(function() { 
      $("#OSB_btn").click(); 
     }); 

     this.waitForSelector('#destinationForPackage', function() { 
      if (this.exists('#destinationForPackage')){ 
       var name = casper.evaluate(function() { 
        return $("#destinationForPackage option[value='" + $("#destinationForPackage").val() + "']").text() 
       }); 
       if (name != "Going To"){ 
        if (name == null){ 
         console.log("it's null"); 
        }else{ 
         name = name.replace("/","_"); 
         casper.capture('Captures/Searches/search_' + name + '.jpg'); 
         console.log("Capturing search_" + name); 
        } 
       } 
      }else{ 
       console.log("Still doesn't exist...retry"); 
       loadSearch(casper,index); 
      } 

     },function(){ 
      console.log("Search page timed-out."); 
     },20000); 
    }); 
} 

它增加了每個循環約3GB。

enter image description here

回答

0

有可能是一個更好的解決原來的問題,但對運行內存速戰速決,儘量setTimeout使未經清盤堆棧中的遞歸調用...

setTimeout(() => loadSearch(casper,index), 0); 

(這個想法假設內存問題是在很長的等待時間內太多的遞歸深度的結果)。

+0

由於timeout參數設置爲0,是不是隻是立即調用該函數?我從來沒有見過像那樣使用setTimeout。 – TheValyreanGroup

+0

由原來的問題,你的意思是我的其他職位?如果是這樣,我愛聽它。 – TheValyreanGroup

+0

@TheValyreanGroup,它立即調用它,但在運行循環的下一回閤中沒有延遲,給當前調用一個彈出堆棧的機會。回覆:最初的問題,我希望我知道在那裏更有幫助。 – danh

1

事實證明這是一個PhantomJS非常着名的問題。 3年以上是一個開放的bug,顯然它與QT Webkit有關。儘管如此,我可以通過在循環過程中關閉每個頁面並重新打開一個新的Phantom頁面來解決這個問題。這是一個有點混亂的解決方法,但內存消耗要少得多。但是,在大約200頁之後,它仍然具有相當高的內存使用量(1GB +)。所以,我把我的腳本分成200塊,並在完成後開始下一個腳本。這是完成的產品,成功地完成沒有太多的內存使用情況。出於某種原因,它在MacOS上使用的次數少於Windows。

casper.start(url,function(){ 
    this.echo('continuing captures...'); 
}).each(searchPages,function(casper,index){ 
    loadSearch(this,index); 
}); 

function loadSearch(casper,index){ 
    var currentTime = new Date(); 
    var month = currentTime.getMonth() + 1; 
    var day = currentTime.getDate() + 1; 
    var year = currentTime.getFullYear(); 
    var dateStart = month + "/" + day + "/" + year; 
    var fortnightAway = new Date(+new Date + 12096e5); 
    var dateEnd = fortnightAway.getMonth() + 1 + "/" + fortnightAway.getDate() + "/" + fortnightAway.getFullYear(); 

    casper.page.close(); 
    casper.page = require('webpage').create(); 

    casper.thenOpen(url,function(){ 
     var myfile = "data-"+year + "-" + month + "-" + day+".html"; 
     this.evaluate(function(j) { 
      document.querySelector('select[name="searchParameters.localeId"]').selectedIndex = j; 
     },index); 
     this.evaluate(function(start) { 
      $("#leaveDate").val(start); 
     },dateStart); 
     this.evaluate(function(end) { 
      $("#returnDate").val(end); 
     },dateEnd); 
     this.evaluate(function() { 
      $("#OSB_btn").click(); 
     }); 
     this.waitForSelector('#destinationForPackage', function() { 
      if (this.exists('#destinationForPackage')){ 
       var name = casper.evaluate(function() { 
        return $("#destinationForPackage option[value='" + $("#destinationForPackage").val() + "']").text() 
       }); 
       if (name != "Going To"){ 
        if (name == null){ 
         console.log("it's null"); 
        }else{ 
         name = name.replace("/","_"); 
         name = name.replace("/","_"); 
         casper.capture('Captures/Searches/search_' + name + '.jpg'); 
         console.log("Capturing search_" + name); 
        } 
       } 
      }else{ 
       console.log("Search failed to load. Retrying"); 
       loadSearch(casper,index); 
      } 

     },function(){ 
      console.log("Search page timed-out. Retrying"); 
      loadSearch(casper,index); 
     },20000); 
    }); 
}