CasperJS:通过URL迭代

时间:2014-06-23 07:58:40

标签: casperjs

我对CasperJS很陌生,但是有没有办法在for循环中打开URL并执行CasperJS命令?例如,此代码无法正常工作:

casper.then(function() {
    var counter = 2013;
    for (i = counter; i < 2014; i++) {
        var file_name = "./Draws/wimbledon_draw_" + counter + ".json";
        // getting some local json files
        var json = require(file_name);
        var first_round = json["1"];
        for (var key in first_round) {
            var name = first_round[key].player_1.replace(/\s+/g, '-');
            var normal_url = "http://www.atpworldtour.com/Tennis/Players/" + name;
            // the casper command below only executes AFTER the for loop is done
            casper.thenOpen(normal_url, function() {
                this.echo(normal_url);
            });
        }
    }
});

而不是Casper每次迭代在每个新URL上调用thenOpen,它只在for循环执行后调用。然后调用Casper thenOpen,并将最后一个值设置为normal_url。是否没有Casper命令让它在for循环中每次迭代都有效?

跟进:我们如何制作casper thenOpen在for循环的当前迭代中返回一个值?

比如说,我需要thenOpen的返回值(如果HTTP状态为404,我需要评估另一个URL,所以我想返回false)。这可能吗?

编辑casper.thenOpen以上电话:

    var status;
    // thenOpen() only executes after the console.log statement directly below
    casper.thenOpen(normal_url, function() {
        status = this.status(false)['currentHTTPStatus'];
        if (status == 200) {
            return true;
        } else {
            return false;
        }
    });
    console.log(status); // This prints UNDEFINED the same number of times as iterations.

2 个答案:

答案 0 :(得分:2)

如果您需要获取上下文,请使用以下示例: https://groups.google.com/forum/#!topic/casperjs/n_zXlxiPMtk

我使用了IIFE(立即调用函数表达式)选项。

例如:

for(var i in links) {
  var link = links[i];

  (function(index) {
    var link = links[index]
    var filename = link.replace(/#/, '');
    filename = filename.replace(/\//g, '-') + '.png';

    casper.echo('Attempting to capture: '+link);
    casper.thenOpen(vars.domain + link).waitForSelector('.title h1', function () {
      this.capture(filename);
    });
  })(i);
}

links可以是一个对象数组,因此如果需要,您的索引是对一组属性的引用...

var links = [{'page':'some-page.html', 'filename':'page-page.png'}, {...}]

答案 1 :(得分:1)

FanchDarren Cook所述,您可以使用IIFE来修复thenOpen步骤中的网址值。

另一种方法是使用 getCurrentUrl 来检查网址。所以改变行

this.echo(normal_url);

this.echo(this.getCurrentUrl());

问题是normal_url引用了最后设置的值而不是当前值,因为它稍后执行。 casper.thenOpen(normal_url, function(){...});不会发生这种情况,因为当前引用会传递给函数。您只是看到了错误的网址,但实际打开了正确的网址。


关于您更新的问题:

casperjs API中的所有then*wait*函数都是步进函数。您传递给它们的函数将被安排并稍后执行(由casper.run()触发)。你不应该在步骤之外使用变量。只需在thenOpen调用中添加更多步骤即可。他们将按正确的顺序安排。此外,您无法从thenOpen返回任何内容。

var somethingDone = false;
var status;
casper.thenOpen(normal_url, function() {
    status = this.status(false)['currentHTTPStatus'];
    if (status != 200) {
        this.thenOpen(alternativeURL, function(){
            // do something
            somethingDone = true;
        });
    }
});
casper.then(function(){
    console.log("status: " + status);
    if (somethingDone) {
        // something has been done
        somethingDone = false;
    }
});

在此示例中,this.thenOpen将在casper.thenOpen之后安排somethingDonetrue将在casper.then内安排i,因为它位于"./Draws/wimbledon_draw_" + i + ".json"之后。


您需要解决一些问题:

  • 您没有使用计数器"./Draws/wimbledon_draw_" + counter + ".json":您可能意味着require而不是JSON.parse
  • 你不能then*一个JSON字符串。有趣的是,你可以要求一个JSON文件。我仍然会使用fs.read来读取文件并解析其中的JSON(wait*)。

关于您的问题......

您没有安排任何命令。只需在thenOpen后面或内部添加步骤({{1}}或{{1}})。