5

我试图点击“下一步”按钮 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 循环中使用的索引。

所以tl; dr:我想舔“下一个”,打印页面源,单击“下一个”,打印页面源,单击“下一个”......继续N次。

4

3 回答 3

7

首先,您可以将值传递给远程页面上下文(即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 进程等,您可能还需要wait在调用 nextPage 之前添加一个:

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)); 
});
于 2013-09-17T03:58:44.490 回答
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('-------------------------');
    });
});
于 2013-09-16T19:29:13.953 回答
1
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() 来启动多个链接

于 2016-09-01T14:26:50.177 回答