我对CasperJS比较陌生,编写了简单的抓取脚本,现在我处理的是一项更艰巨的任务:我想从网址列表中删除某些数据,但有些页面有时会“失败“,我有一个验证码解决服务,因为这些页面中有一些默认情况下有验证码,但是phantomjs在呈现一些验证码方面相当不一致,有时它们会加载,有时它们不会加载。
我认为解决方案是使用无法加载验证码的页面重新运行脚本以获取我需要的数据量。但我似乎没有让它运行,我想到用整个事物创建一个函数然后在casper.run()
方法内部调用它并检查刮除的数据量是否满足我需要的最小值,如果没有重新运行,但我真的不知道如何实现它,至于我所看到的casperjs在调用函数之前将步骤添加到堆栈中(如果我错了,请纠正我)。此外,我正在考虑使用run.complete
事件,但不确定如何做到这一点。我的脚本是这样的:
// This variable stores the amount of data collected
pCount = 0;
urls = ["http://page1.com","http://page2.com"];
// Create casperjs instance...
casper.start();
casper.eachThen(urls, function(response) {
if (pCount < casper.cli.options.number) {
casper.thenOpen(response.data, function(response) {
// Here is where the magic goes on
})
}
})
casper.run();
无论如何我可以在函数中包装casper.eachThen()
块并执行类似的操作吗?
casper.start();
function sample () {
casper.eachThen(urls, function(response) {
if (pCount < casper.cli.options.number) {
casper.thenOpen(response.data, function(response) {
// Here is where the magic goes on
})
}
})
}
casper.run(sample);
另外,我尝试使用slimerjs作为引擎以避免“不一致”,但我无法在__utils__.sendAjax()
内部使用casper.evaluate()
方法,所以这是一个交易破坏者。或者有没有办法在单独的实例中异步执行GET请求?如果是的话,我将非常感谢您的建议
更新:我从未设法用casperjs解决它,但我找到了针对我的特定用例的解决方法,请查看我的答案以获取更多信息
答案 0 :(得分:1)
也许使用后退功能,就像这样:
casper.start()
.thenOpen('your url');
.then(function(){
var count = 0;
if (this.exists("selector contening the captcha")){
//continue the script
}
else if (count==3){
this.echo("in 3 attempts, it failed each time");
this.exit();
}
else{
count++;
casper.back();//back to the previous step, so will re-open the url
}
.run();
答案 1 :(得分:1)
我从未找到过从casper那里做到这一点的方法,这就是我解决它的方法:
有一个程序A,它管理用户输入(在我的例子中用C#编写)。该程序A是执行casperjs脚本并读取它的输出的程序。如果我需要重新运行脚本,我只输出一条带有一些规范的消息,以便我在程序A中捕获它。
这可能不是最好的方式,但它对我有用。希望它有所帮助