我正在使用 CasperJS 抓取多个页面,但我卡住了。
最大页数为 200,但如果下面的 XPath 不存在(对于第 200 页之前的页面),我想停止执行。
如何设置i
变量?
var casper = require('casper').create();
var x = require('casper').selectXPath;
for (var i=1; i <=200; i++) {
casper.wait(6000, function() {
casper.thenClick(x('//*[@id="mArticle"]/div[2]/a['+i+']'), function (){
console.log('Searching dic');
words = words.concat(this.evaluate(getWords));
});
});
}
最佳答案
CasperJS 提供了 exists()
功能。因此,您可以像这样重写代码:
for (var i=1; i <=200; i++) {
(function(i){
casper.wait(6000, function() {
var button = x('//*[@id="mArticle"]/div[2]/a['+i+']');
if (!this.exists(button)) {
this.echo(i + " not available");
return; // the following `thenClick()` is not executed
}
this.thenClick(button, function (){
console.log('Searching dic');
words = words.concat(this.evaluate(getWords));
});
});
})(i);
}
我还添加了一个 IIFE,以便您在回调中拥有正确的 i
。有关详细信息,请参阅 JavaScript closure inside loops – simple practical example .
这是有效的,但是如果假设如果链接 100 不存在,那么链接 101 和 102 等也不存在,那么它不是很有效。您会等待很多时间(6 秒乘以 100)。在这种情况下,由于 CasperJS 的异步特性,您需要递归地执行此操作:
function execOnce(casper, i, max){
// end condition
if (i === max) {
return;
}
casper.wait(6000, function() {
var button = x('//*[@id="mArticle"]/div[2]/a['+i+']');
if (!this.exists(button)) {
this.echo(i + " not available");
return;
}
this.thenClick(button, function (){
console.log('Searching dic');
words = words.concat(this.evaluate(getWords));
// recursive step
execOnce(this, i+1, max);
});
});
};
casper.start(url);
// start the recursive chain
casper.then(function(){
execOnce(this, 1, 200);
});
casper.run();
请注意,现在您已经递归地拥有它,您可以通过在页面上明确查看有什么和没有什么来定义适当的结束条件。
关于javascript - 在 CasperJS 中异步单击时如何停止循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32423373/