【问题标题】:Re-run casperjs script重新运行 casperjs 脚本
【发布时间】:2014-04-19 20:12:14
【问题描述】:

我对 CasperJS 比较陌生,写过简单的抓取脚本,现在我面临一项更艰巨的任务:我想从 url 列表中抓取某种数据,但有时有些页面“失败”,我有一个验证码解决服务,因为其中一些页面默认有验证码,但是 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 作为引擎来避免“不一致”,但我无法在 casper.evaluate() 中使用 __utils__.sendAjax() 方法,所以它是一个交易破坏者。或者有没有办法在单独的实例中异步执行 GET 请求?如果是这样,我会很感激你的建议

更新:我从来没有设法用 casperjs 解决它,但我还是找到了针对我的特定用例的解决方法,请查看我的答案以获取更多信息

【问题讨论】:

  • 好吧,我又看到了这个问题,this topic 可能会对你有所帮助。

标签: javascript phantomjs casperjs slimerjs


【解决方案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();

【讨论】:

  • :O 从来没有真正检查过 back() 我认为它确实会像单击浏览器后退按钮一样转到上一页。我一定会试一试的。我会及时通知你
  • 是的,老实说我没有尝试,请随时通知我:)
  • 这行不通,就像我想的那样,back() 在浏览器的历史 中倒退了一步,而不是在步骤的堆栈中。还是谢谢
  • 是的,显然没有本地方法可以做到这一点:github.com/n1k0/casperjs/issues/1。但是我们可以对条件和 repeat() 方法做同样的事情。我会尽快尝试的。
【解决方案2】:

我从来没有从 casper 找到一种方法来做到这一点,这就是我解决它的方法:

有一个程序 A,它管理用户输入(在我的例子中是用 C# 编写的)。该程序 A 是执行 casperjs 脚本并读取其输出的程序。如果我需要重新运行脚本,我只是输出一条带有一些规范的消息,以便我在程序 A 中捕获它。

这可能不是最好的方法,但它对我有用。希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多