javascript 如何在casperjs中循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18835159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 13:22:29  来源:igfitidea点击:

How to for loop in casperjs

javascriptphantomjscasperjs

提问by jpmorris

I am trying to click a 'next' button N number of times and grab the page source each time. I understand that I can run an arbitrary function on the remote website, so instead of click() I just use the remote function nextPage() How do I run the following, an arbitrary number of times:

我试图点击“下一步”按钮 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' here is an index I triedto use in a javascript for loop.

'i' 这里是我试图在 javascript for 循环中使用的索引。

So tl;dr: I want lick 'next', print pages source, click 'next', print page source, click 'next'... continue that N number of times.

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

回答by sudipto

First, you can pass a value to the remote page context (i.e. to thenEvaluatefunction like this:

首先,您可以将一个值传递给远程页面上下文(即thenEvaluate功能如下:

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

However, Casper#repeatmight not be a good function to use here as the loop would NOT wait for each page load and then capture the content.

但是,Casper#repeat在这里使用可能不是一个好的函数,因为循环不会等待每个页面加载然后捕获内容。

You may rather devise a event based chaining.

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

The work-flow of the code would be:

代码的工作流程是:

  1. Have a global variable (or at-least a variable accessible to the functions mentioned below) to store the countand the limit.

  2. listen to the load.finishedevent and grab the HTML here and then call the next page.

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

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

A simplified code can be:

简化的代码可以是:

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();

NOTE: If you pages with high load of JS processes etc. you may also want to add a waitbefore calling the nextPage :

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

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

[EDIT ADDED] The following event listeners will help you debug.

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

// 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)); 
});

回答by hexid

You could try using Casper#repeat

你可以尝试使用 Casper#repeat

This should do, for the most part, what you want:

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

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('-------------------------');
    });
});

回答by waza123

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.
            });
        }
    });
});

This is answer to question, how to use for() in casperjs to launch several links

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