我为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:
我抓取的所有网址都包含我要搜索的资源网址。
答案 0 :(得分:1)
所有wait*
和then*
函数都是CasperJS中的步骤。因此stepTimeout
用于所有这些waitTimeout
,而wait*
仅用于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