CasperJS не хватает памяти

1

Я запускаю следующий скрипт с 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 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);
    });
}

И он добавляет около 3 ГБ за цикл.

Изображение 174551

Теги:
casperjs

2 ответа

1

Ну, оказывается, это очень известная проблема с PhantomJS. 3+ лет как открытая ошибка, и, видимо, это как-то связано с 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 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);
    });
}
0

Возможно, было лучшее решение исходной проблемы, но для быстрого исправления setTimeout памяти попробуйте setTimeout сделать рекурсивный вызов без извлечения стека...

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

(Эта идея предполагает, что проблема с памятью является результатом слишком большой рекурсивной глубины в течение длительного времени ожидания).

  • 0
    Разве это не вызывает функцию сразу же, так как для параметра timeout установлено значение 0? Я никогда не видел, чтобы setTimeout использовался таким образом.
  • 0
    А под оригинальным номером вы имеете в виду мой другой пост? Если так, то я люблю это слышать.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню