CasperJS中的waitTimeout和stepTimeout有什么区别?

时间:2014-10-23 06:54:19

标签: javascript casperjs

我为casperjs定义了以下设置

var casper = require('casper').create({
    waitTimeout: 50000,
    stepTimeout: 50000,
    verbose: true,
    viewportSize: {
      width: 1400,
      height: 768
    },
    pageSettings: {
      "userAgent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36',
      "loadImages": false,
      "loadPlugins": false,         
      "webSecurityEnabled": false,
      "ignoreSslErrors": true
    },
    onStepTimeout: function() {
      this.echo("Step timed out ");
      var step = casper.getStepNumber();
      casper.gotoStep(step+1);
    }
});

我在casperjs模块中添加了这些函数:

Casper.prototype.getStepNumber = function getStepNumber() {
    "use strict";
    return this.step;
};
Casper.prototype.gotoStep = function gotoStep(stepNum) {
    "use strict";
     var steps = this.steps,
         last = steps.length;
     this.checkStarted();
     this.clear();
     this.step = Math.min(stepNum,last);
     return this;
};

我在数组'urlArray'中有一个url列表。我将逐一打开所有这些网址:

casper.start().each(urlArray, function(self, url) {
    casper.thenOpen(url, function() {
        this.echo("INFO:"+"\t"+url+"\t"+"Opened."+"\n");
    }); 
});

打开网址后,我在资源中寻找一个特定的字符串,一旦到达那里,我只是将该特定网址打印到stdout并中止当前请求,如下所示

casper.on('resource.requested', function(resource,request) {
    var url = resource.url;
    if(url.indexOf("some string") !== -1) {
        this.echo("url: "+url);
        request.abort();
    }
});

问题:Casper在到达我正在寻找的资源网址之前会进入下一页(来自urlArray),在某些情况下我会得到'stepTimeout'。如何限制casper等待我正在查找的资源网址而不获取stepTimeOut(假设我将有60秒作为stepTimeOut)并且不跳过当前网址。

当前输出为:

INFO: url1 Opened.
INFO: url2 Opened.
INFO: url3 Opened.
prints the resource url that I am looking for.
INFO: url4 pened.
INFO: url5 Opened.
INFO: url6 Opened.
INFO: url7 Opened.
INFO: url8 Opened.
prints the resource url that I am looking for.
INFO: url9 Opened.
INFO: url10 Opened.

Note:我抓取的所有网址都包含我要搜索的资源网址。

2 个答案:

答案 0 :(得分:1)

所有wait*then*函数都是CasperJS中的步骤。因此stepTimeout用于所有这些waitTimeout,而wait*仅用于stepTimeout函数。

stepTimeout:

  

类型:数字
  默认值:null
  最大步长超时(以毫秒为单位);设置后,必须在达到此超时值之前执行每个已定义的步骤函数。您可以定义onStepTimeout()回调来捕获这种情况。默认情况下,脚本将在die()中显示错误消息。

上述文档告诉您需要知道的一切。要么您没有设置casper.options.onStepTimeout,要么将处理程序die()覆盖为不thenOpen的内容。

您遇到此问题的原因可能是因为page.resource.requested步骤必然会打开该页面。如果它没有成功,那么在一段时间内达到超时,因此脚本就会死掉。

其他注意事项:

您说您希望等到特定资源(如果请求),但您不想实际加载它。看来你不是在谈论这个页面,而是来自页面的一些资源(js,css,img,ajax调用等)。您应该将事件处理程序从resource.requested更改为url.indexOf("some string") 在您处理此问题时,请将url.indexOf("some string") !== -1更改为casper.start().each(urlArray, function(self, url) { casper.thenOpen(url, function() { this.echo("INFO:"+"\t"+url+"\t"+"Opened."+"\n"); }).waitForResource(function test(resource){ return resource.url.indexOf("some string") !== -1; }, function then(){ this.echo("INFO: resource loaded"); }); }); ,否则您将无法匹配该网址的协议。

如果资源确实存在于您加载的每个页面上,那么您可以

abort

但是你不能在事件处理程序中{{1}}请求,因为它可能不起作用。

答案 1 :(得分:0)

基本上waitTimeout是你想要等待获得任何waitSomething()的结果的时间(毫秒)。

所以waitTimeout:10000将为任何函数wait *(waitForUrl(),waitForSelector()等等)提供10秒的响应并返回一些东西。

根据定义,

stepTimeout是“以毫秒为单位的最大步长;当设置时,每个已定义的步骤函数必须在达到此超时值之前执行。您可以定义onStepTimeout()回调以捕获这种情况。默认情况下,脚本将die()并显示错误消息。“

这意味着您可以为任何步骤函数设置stepTimeout,以强制在waitTimeout之前执行(或中止)步骤。

这是一个例子:CasperJS skip step on timeout

这对链式动作非常有用。

编辑:在CasperJS FAQ上有另一个例子:http://docs.casperjs.org/en/1.1-beta2/faq.html#how-does-then-and-the-step-stack-work