如何在条件满足时打破CasperJS的重复功能?

时间:2014-12-08 14:04:13

标签: javascript casperjs

我想知道我是否可以打破casper.repeat循环。

我有这样做的脚本..:

搜索谷歌代理商001,代理商002,代理商003,代理商004,代理商005,代理商006 .......'直到代理商011。

我希望它在找到文本" James Bond"后停止循环。

现在它找到它,打印出来,但我不知道是否以及如何停止casper.repeat循环。

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.com/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();

3 个答案:

答案 0 :(得分:3)

repeat循环在导航开始之前完成。在通过repeat触发执行之前,通过将所有迭代展开到队列中立即执行casper.run。在使用同步代码时,您无法中断repeat循环,并且在实际安排步骤时,您肯定无法中断repeat循环。但是你仍然可以通过使用递归来实现你想要达到的目的。

您需要将循环体定义为函数并使其尾递归。

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();

在您的情况下,可能需要一个全局变量来跟踪每个&#34;循环中的内容。迭代。

答案 1 :(得分:3)

你应该了解casper.repeat();的工作原理 重复的内部结构如下。取自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;
};

从这里你可以看到一旦重复被调用,即重复(numTimes,你的函数)。

您可以考虑&#34;然后&#34;参数,就像你传递给重复的函数一样。所以一旦调用发生,它将在for循环中工作。所以在通话结束后打破重复是不可能的。在您要传递给repeat的函数内使用Casper.byPassIf Casper.byPassUnless以绕过执行。 使用此功能,您可以跳过功能中的步骤。这意味着重复只有在达到最终计数后才会停止。但它不会执行任何步骤,因为您绕过了具有上述功能的步骤。旁路功能的进一步说明不在此范围内。实际上它是你可以尝试的工作。希望它会有所帮助。如果需要进一步澄清,请随时询问。享受!!!

示例下面的循环将执行10次,但只打印1到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++;
    });     
});

答案 2 :(得分:1)

这个怎么样?

casper.keep_looping = true;

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

由于没有办法打破casper.repeat循环(至少我没有在文档中找到它),那么可能避免执行循环代码就足够了。上面的代码将运行循环,直到“some_counter”耗尽,但如果将“i_no_longer_want_to_loop”变量设置为true,则不会执行循环中的代码。