CasperJS耗尽内存

时间:2017-06-03 20:17:10

标签: javascript casperjs

我用CasperJS运行以下脚本,在通过数组的大约1/3之后,它开始耗尽交换空间,机器变得非常慢。我在这做错了什么?

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

2 个答案:

答案 0 :(得分:1)

事实证明,这是PhantomJS的一个众所周知的问题。作为一个开放的bug 3年多,显然它与QT Webkit有关。尽管如此,我能够通过在循环期间关闭每个页面并重新打开一个新的Phantom页面来解决它。这有点像hacky的解决方案,但内存消耗要少得多。但是,在大约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);
    });
}

答案 1 :(得分:0)

对于原始问题可能有一个更好的解决方案,但为了快速解决内存耗尽的问题,请尝试setTimeout进行递归调用而不要清理堆栈......

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

(这个想法假设内存问题是在很长的等待时间内递归深度过多的结果。)