javascript - How to break CasperJS' repeat function when a condition is fulfilled? - Stack Overflow

I want to know if i can break a casper.repeat loop.I have this script which does this..:Searches google

I want to know if i can break a casper.repeat loop.

I have this script which does this..:

Searches google for agent 001, agent 002, agent 003, agent 004, agent 005, agent 006..... ....'til agent 011.

I want it to stop looping after it finds the text "James Bond".

Now it finds it, prints it out, but i dont know if and how to stop the casper.repeat loop.

var casper = require("casper").create({
  clientScript: ["jquery.min.js"],
  verbose: true,
  logLevel: "info"
});
var mouse = require("mouse").create(casper);
var x = require('casper').selectXPath;
var webPage = require('webpage');
var page = webPage.create();

casper.on("remote.message", function(msg){
    this.echo("remote> " + msg);
    var test = msg;
    if( test.indexOf('James Bond') >= 0){
    casper.echo("Am Gasit James Bond");
}
});

casper.userAgent('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36')
casper.start("", function() {
      this.echo("\nINCEPUTUL INCEPUTULUI TITLUL PAGINII IN START (LINIA DE MAI JOS)\n"+this.getTitle()+"\n");
      }).viewport(1366,768);
casper.options.waitTimeout = 30000;
var variabila_mea = "agent ";
var numTimes = 11, count = 1;
casper.repeat(numTimes, function() {
if (count < 10) {
var i = "00"+count;
    casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
        this.evaluate(function(count, variabila_mea, i, numar) {
            document.getElementsByClassName('gbqfif')[0].value=variabila_mea+i;
            document.forms[0].submit();
            nextPage(count);
        }, ++count,variabila_mea , i,"00000");
        console.log(variabila_mea);

        casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
            var inputValue = casper.evaluate(function () {
                console.log("\n\n\n"+document.getElementsByClassName('rc')[0].outerHTML+"\n\n\n");
            });
        });

        casper.wait(1000, function(){
        console.log("\n_____________________");
        casper.capture('aa'+i+'.png');
        console.log("_____________________\n");
        });
    });

    } else if (count < 100 && count > 9) {
    var i = "0"+count;
    casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
        this.evaluate(function(count, variabila_mea, i, numar) {
            document.getElementsByClassName('gbqfif')[0].value=variabila_mea+i;
            document.forms[0].submit();
            nextPage(count);
        }, ++count,variabila_mea , i,"00000");
        console.log(variabila_mea);

        casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
            var inputValue = casper.evaluate(function () {
                console.log("\n\n\n"+document.getElementsByClassName('rc')[0].outerHTML+"\n\n\n");
            });
        });

        casper.wait(1000, function(){
        console.log("\n_____________________");
        casper.capture('aa'+i+'.png');
        console.log("_____________________\n");
        });
    });

    } else {
    var i = count;
    casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
        this.evaluate(function(count, variabila_mea, i, numar) {
            document.getElementsByClassName('gbqfif')[0].value=variabila_mea+i;
            document.forms[0].submit();
            nextPage(count);
        }, ++count,variabila_mea , i,"00000");
        console.log(variabila_mea);

        casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
            var inputValue = casper.evaluate(function () {
                console.log("\n\n\n"+document.getElementsByClassName('rc')[0].outerHTML+"\n\n\n");
            });
        });

        casper.wait(1000, function(){
        console.log("\n_____________________");
        casper.capture('aa'+i+'.png');
        console.log("\n_____________________");
        });
    });

    }

});
casper.run();

I want to know if i can break a casper.repeat loop.

I have this script which does this..:

Searches google for agent 001, agent 002, agent 003, agent 004, agent 005, agent 006..... ....'til agent 011.

I want it to stop looping after it finds the text "James Bond".

Now it finds it, prints it out, but i dont know if and how to stop the casper.repeat loop.

var casper = require("casper").create({
  clientScript: ["jquery.min.js"],
  verbose: true,
  logLevel: "info"
});
var mouse = require("mouse").create(casper);
var x = require('casper').selectXPath;
var webPage = require('webpage');
var page = webPage.create();

casper.on("remote.message", function(msg){
    this.echo("remote> " + msg);
    var test = msg;
    if( test.indexOf('James Bond') >= 0){
    casper.echo("Am Gasit James Bond");
}
});

casper.userAgent('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36')
casper.start("https://www.google./ncr", function() {
      this.echo("\nINCEPUTUL INCEPUTULUI TITLUL PAGINII IN START (LINIA DE MAI JOS)\n"+this.getTitle()+"\n");
      }).viewport(1366,768);
casper.options.waitTimeout = 30000;
var variabila_mea = "agent ";
var numTimes = 11, count = 1;
casper.repeat(numTimes, function() {
if (count < 10) {
var i = "00"+count;
    casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
        this.evaluate(function(count, variabila_mea, i, numar) {
            document.getElementsByClassName('gbqfif')[0].value=variabila_mea+i;
            document.forms[0].submit();
            nextPage(count);
        }, ++count,variabila_mea , i,"00000");
        console.log(variabila_mea);

        casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
            var inputValue = casper.evaluate(function () {
                console.log("\n\n\n"+document.getElementsByClassName('rc')[0].outerHTML+"\n\n\n");
            });
        });

        casper.wait(1000, function(){
        console.log("\n_____________________");
        casper.capture('aa'+i+'.png');
        console.log("_____________________\n");
        });
    });

    } else if (count < 100 && count > 9) {
    var i = "0"+count;
    casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
        this.evaluate(function(count, variabila_mea, i, numar) {
            document.getElementsByClassName('gbqfif')[0].value=variabila_mea+i;
            document.forms[0].submit();
            nextPage(count);
        }, ++count,variabila_mea , i,"00000");
        console.log(variabila_mea);

        casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
            var inputValue = casper.evaluate(function () {
                console.log("\n\n\n"+document.getElementsByClassName('rc')[0].outerHTML+"\n\n\n");
            });
        });

        casper.wait(1000, function(){
        console.log("\n_____________________");
        casper.capture('aa'+i+'.png');
        console.log("_____________________\n");
        });
    });

    } else {
    var i = count;
    casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
        this.evaluate(function(count, variabila_mea, i, numar) {
            document.getElementsByClassName('gbqfif')[0].value=variabila_mea+i;
            document.forms[0].submit();
            nextPage(count);
        }, ++count,variabila_mea , i,"00000");
        console.log(variabila_mea);

        casper.waitForSelector(x('//*[@id="gbqfq"]'), function(){
            var inputValue = casper.evaluate(function () {
                console.log("\n\n\n"+document.getElementsByClassName('rc')[0].outerHTML+"\n\n\n");
            });
        });

        casper.wait(1000, function(){
        console.log("\n_____________________");
        casper.capture('aa'+i+'.png');
        console.log("\n_____________________");
        });
    });

    }

});
casper.run();
Share Improve this question edited Dec 8, 2014 at 14:26 Artjom B. 62k26 gold badges135 silver badges230 bronze badges asked Dec 8, 2014 at 14:04 user215379user215379 1194 silver badges11 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

The repeat loop is finished before the navigation has even begun. repeat is executed immediately by unrolling all the iterations into a queue before the execution is even triggered through casper.run. You cannot break a repeat loop when synchronous code is used and you certainly cannot break a repeat loop when steps are actually scheduled. But you can still achieve what you want to achieve by using recursion.

You need to define your looping body as a function and make it tail recursive.

function loopBody(index, numTimes){
    if (conditionFailed || index >= numTimes) {
        return;
    }
    this.then(function(){
        // do something useful
    });
    this.then(function(){
        loopBody.call(this, index+1, numTimes);
    });
}

casper.start(url).then(function(){
    loopBody.call(this, 0, numTimes);
}).run();

In your case a global variable is probably needed to track what is found in each "loop" iteration.

You should understand the working of casper.repeat(); Internal structure of repeat is below. Taken from git hub

/**
 * Repeats a step a given number of times.
 * @param  Number    times  Number of times to repeat step
 * @aram   function  then   The step closure
 * @return Casper
 * @see    Casper#then
 */
Casper.prototype.repeat = function repeat(times, then) {
    "use strict";
    for (var i = 0; i < times; i++) {
        this.then(then);
    }
    return this;
};

From this you can see that once repeat is called ie repeat (numTimes,your function).

You can consider "then" parameter as what ever the function you are passing to repeat. So once the call is happened it will work inside a for loop. So Breaking the Repeat after the call is not possible. Use Casper.byPassIf Casper.byPassUnless inside your function which you are passing to the repeat in order to bypass the execution. Using this you an skip the steps inside your function. Which means repeat will stop only after reaching it end count. But it won't perform any steps because you are bypassing those with above mentioned functions. Further explanation of bypass function not es under this scope of question. Actually it is work around you can try. Hope it will be helpful. If needed further clarification please feel free to ask. Enjoy !!!

Example the below loop will execute 10 times but only print 1 to 5.

var i=1;
loopcount=10
casper.repeat(loopCount, function() {
    casper.thenBypassIf(function() {
        return i >5;
    }, 1);
    casper.then(function() {
        this.echo (i);
    });
    casper.then(function() {
        i++;
    });     
});

How about this?

casper.keep_looping = true;

casper.repeat(some_counter, function() {
    if (casper.keep_looping)
    {
        if (i_no_longer_want_to_loop) {
            casper.keep_looping = false;
        }
    }
});

Since there is no way to break the casper.repeat loop (at least I haven't found it in the docs), then maybe avoiding the execution of the in-loop code is enough. The code above will run the loop until the "some_counter" is exhausted but the code in the loop will not be executed if you set the "i_no_longer_want_to_loop" variable to true.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744706332a4589076.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信