我对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.
答案 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)
如Fanch和Darren 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
之后安排somethingDone
,true
将在casper.then
内安排i
,因为它位于"./Draws/wimbledon_draw_" + i + ".json"
之后。
您需要解决一些问题:
"./Draws/wimbledon_draw_" + counter + ".json"
:您可能意味着require
而不是JSON.parse
then*
一个JSON字符串。fs.read
来读取文件并解析其中的JSON(wait*
)。关于您的问题......
您没有安排任何命令。只需在thenOpen
后面或内部添加步骤({{1}}或{{1}})。