2017-06-03 145 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); 
    }); 
}