【问题标题】:Asynchronous Process inside a casperjs script for while loop用于while循环的casperjs脚本中的异步进程
【发布时间】:2016-06-01 07:30:16
【问题描述】:

我正在使用 while 循环从 csv 文件中打开用户名列表。对于其中的每个用户名,我必须打开一个 URL 并将页面转储到一个文件中。

但是,casper.thenOpen 总是只运行一次。我从Asynchronous Process inside a javascript for loop 了解到这是因为它是一个异步过程。我需要对下面的代码做同样的事情:

casper.then(function(){
    stream = fs.open('usernames.csv', 'r');
    targetusername = stream.readLine();         
    i = 0;

    while(targetusername) {                 
        var url = "http://blablalb" + targetusername;       
        console.log("current url is " + url);

        casper.thenOpen(url, function() {
            console.log ("I am here");
            fs.write(targetusername,this.getTitle() + "\n",'w');        
            fs.write(targetusername,this.page.plainText,'a');       
        });

        targetusername = stream.readLine();
        i++;
    }

});

casper.thenOpen 总是只运行一次,给我这个输出:

current url is first_url
current url is second_url
current url is third_url
I am here

我需要的是这样的

current url is first_url
I am here
current url is second_url
I am here
current url is third_url
I am here

为了让 while 循环正确运行,我正在拔头发!

【问题讨论】:

  • 撞!有人在吗?

标签: javascript casperjs


【解决方案1】:

我认为该代码没有任何问题。我写这段代码是为了测试(基本上和你的代码一样):

var casper = require('casper').create();

var url_list = [
    'http://phantomjs.org/',
    'https://github.com/',
    'https://nodejs.org/'
]

casper.start()

casper.then(function () {
        for (var i = 0; i < url_list.length; i++) {
            casper.echo('assign a then step for ' + url_list[i])
            casper.thenOpen(url_list[i], function () {
                casper.echo("current url is " + casper.getCurrentUrl());
            })
        }
    }
)

casper.run()

输出:

assign a then step for http://phantomjs.org/
assign a then step for https://github.com/
assign a then step for https://nodejs.org/
current url is http://phantomjs.org/
current url is https://github.com/
current url is https://nodejs.org/en/

如您所见,它打开了每个 url。


让我们来回答你的问题:

Q1:为什么不这样输出:

current url is first_url
I am here
current url is second_url
I am here
current url is third_url
I am here

A1:因为 CasperJS 首先分配步骤,更准确地说,将步骤推送到堆栈,然后从堆栈中弹出步骤,然后运行该步骤。请查看great answer 了解更多信息。

Q2:为什么不输出为(为什么循环只运行 1 次):

current url is first_url
current url is second_url
current url is third_url
I am here
I am here
I am here

A2:您可能会在打开第二个 url 时遇到一些异常,并且 PhantomJS 崩溃。此代码可以帮助您了解发生了什么:

var casper = require('casper').create({
    verbose: true,
    logLevel: "debug",
}); //see more logs

casper.on('error', function (msg, backtrace) {
    var msgStack = ['PHANTOM ERROR: ' + msg];
    if (backtrace && backtrace.length) {
        msgStack.push('TRACE:');
        backtrace.forEach(function(t) {
            msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : ''));
        });
    }
    this.log(msgStack.join('\n'), "error");
});// watch the error event which PhantomJS emits

【讨论】:

  • 感谢您的回复,但您知道为什么我的代码会给出该输出吗?我什至用 for 循环替换了 while 循环,并显示了相同的输出
  • @SoCRaT 正如我所说:You may meet some exceptions in opening second url and PhantomJS crashes,那么您是否尝试过我的代码来收集我的错误日志?与您的循环无关(whilefor 无关紧要)。
  • @SoCRaT 你对我的回答还有疑问吗?
  • 嗨,我可以使用重复函数解决它以产生我需要的结果。我会马上发布。非常感谢您的帮助。
【解决方案2】:

我可以达到我需要的确切输出:

current url is first_url
I am here
current url is second_url
I am here
current url is third_url
I am here

使用repeat函数,如下:

casper.then(function(){
    stream = fs.open('usernames.csv', 'r');        

    casper.repeat(3, function() {

        targetusername = stream.readLine(); 
        var url = "http://blablalb" + targetusername;       
        console.log("current url is " + url);

        casper.thenOpen(url, function() {
            console.log ("I am here");
            fs.write(targetusername,this.getTitle() + "\n",'w');        
            fs.write(targetusername,this.page.plainText,'a');       
        });

    }

)});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 2018-09-14
    • 2019-07-04
    • 1970-01-01
    相关资源
    最近更新 更多