如何在 casperjs 中进行循环

How to for loop in casperjs

本文关键字:循环 casperjs      更新时间:2023-09-26

我正在尝试单击"下一步"按钮N次,每次都抓取页面源代码。 我知道我可以在远程网站上运行任意函数,所以我只使用远程函数 nextPage() 而不是 click() 如何运行以下内容,任意次数:

var casper = require('casper').create();
casper.start('http://www.example.com', function() {
    this.echo(this.getHTML());
    this.echo('-------------------------');
    var numTimes = 4, count = 2;
    casper.repeat(numTimes, function() {
        this.thenEvaluate(function() {
            nextPage(++count);
        });
        this.then(function() {
            this.echo(this.getHTML());
            this.echo('-------------------------');
        });
    });
});

这里的"i"是我试图在javascript for loop中使用的索引。

所以 tl;dr:我想舔'下一个',打印页面源,点击"下一步",打印页面源,点击"下一步"...继续N次。

首先,您可以将一个值传递给远程页面上下文(即thenEvaluate像这样函数:

    this.thenEvaluate(function(remoteCount) {
        nextPage(remoteCount);
    }, ++count);

但是,Casper#repeat可能不是一个适合在此处使用的功能,因为循环不会等待每个页面加载然后捕获内容。

您可能更愿意设计一个基于事件的链接。

代码的工作流程将是:

  1. 有一个全局变量(或至少一个可供下面提到的函数访问的变量)来存储countlimit

  2. 收听load.finished事件并在此处获取 HTML,然后调用下一页。

简化的代码可以是:

var casper = require('casper').create();
var limit = 5, count = 1;
casper.on('load.finished', function (status) {
    if (status !== 'success') {
        this.echo ("Failed to load page.");
    }
    else {
        this.echo(this.getHTML());
        this.echo('-------------------------');
    }

    if(++count > limit) {
        this.echo ("Finished!");
    }
    else {
        this.evaluate(function(remoteCount) {
            nextPage(remoteCount);
            // [Edit the line below was added later]
            console.log(remoteCount);
            return remoteCount;
        }, count);
    }
});
casper.start('http://www.example.com').run();

注意:如果您的页面具有高负载的JS进程等,您可能还需要在调用nextPage之前添加wait

this.wait( 
   1000, // in ms
   function () {
        this.evaluate(function(remoteCount) {
            nextPage(remoteCount);
        }, count);
   }
);     

[编辑已添加] 以下事件侦听器将帮助您进行调试。

// help is tracing page's console.log 
casper.on('remote.message', function(msg) { 
    console.log('[Remote Page] ' + msg); 
}); 
// Print out all the error messages from the web page 
casper.on("page.error", function(msg, trace) { 
    casper.echo("[Remote Page Error] " + msg, "ERROR"); 
    casper.echo("[Remote Error trace] " + JSON.stringify(trace, undefined, 4)); 
});

你可以尝试使用Casper#repeat

在大多数情况下,这应该可以满足您的需求:

var numTimes = 10, count = 1;
casper.repeat(numTimes, function() {
    this.thenEvaluate(function(count) {
        nextPage(count);
    }, ++count);
    this.then(function() {
        this.echo(this.getHTML());
        this.echo('-------------------------');
    });
});
var global_page_links = [];
casper.then(function(){
    for(var i=1; i<=5; i++){    
        // you just add all your links to array, and use it in casper.each()
        global_page_links.push(YOUR_LINK);
    }
    this.each(global_page_links, function(self, link) {
        if (link){
            self.thenOpen(link, function() {
                console.log("OPENED: "+this.getCurrentUrl());
                // do here what you need, evaluate() etc.
            });
        }
    });
});

这是问题的答案,如何在casperjs中使用for()来启动几个链接