我正在尝试使用casperjs进行一些测试,这里的某些情况是:
从下拉菜单中提取城市名称(已经完成)
然后选择每个城市(
casper.fill()
),这将导致加载新内容 页面上的内容和网址更改,(成功,使用单个城市名称进行测试,失败,循环显示城市名称列表)进一步了解新加载的商品链接(新页面),
最后,抓住每个页面的内容
我试图循环遍历城市列表并在每个周期中完成所有工作。但问题是CasperJs
尝试立即为每个城市设置<option>
字段值,而不执行循环内的其余代码:
casper.then(function() {
var citiesLength = cities.length;
for (var i = 0; i < citiesLength; i++) {
this.fill('form.wpv-filter-form',{ //setting drop-down field value to the city names in order of the items in the array
'city[]': cityNames[i]
});
// Apparently the code below (to the end of the loop) doesn't get executed
casper.thenEvaluate(function() {
// Here the url change is being checked to know when the new content is loaded:
var regexString = '(\\?)(city)(\\[\\])(=)(' + cityNames[i] + ')&';
var regex = new RegExp(regexString, "igm");
this.waitForUrl(regex, function(){
var name = this.getHTML('.kw-details-title');
link = this.evaluate(getFirstItemLink); // for test, just getting the first item's link
casper.open(link).then(function(){
this.echo("New Page is loaded......");
// Grab the single item contents
});
});
});
}
这是日志(缩短为3个城市):
[debug] [remote] Set "city[]" field value to city1
[info] [remote] attempting to fetch form element from selector: 'form.wpv-filter-form'
[debug] [remote] Set "city[]" field value to city2
[info] [remote] attempting to fetch form element from selector: 'form.wpv-filter-form'
[debug] [remote] Set "city[]" field value to city3
[info] [remote] attempting to fetch form element from selector: 'form.wpv-filter-form'
[info] [remote] attempting to fetch form element from selector: 'form.wpv-filter-form'
[info] [remote] attempting to fetch form element from selector: 'form.wpv-filter-form'
[info] [phantom] Step anonymous 5/5: done in 123069ms.
[info] [phantom] Step _step 6/79 https ://domain.com/section/ (HTTP 200)
[info] [phantom] Step _step 6/79: done in 123078ms.
P.s:使用casper.open()
是获得二级页面(项目页面)的好方法吗?在获取内容后,我是否需要以某种方式关闭它们?
由于
答案 0 :(得分:1)
很难给出准确的答案,因为您的问题无法重现。但是,我在你的脚本中注意到了几个问题......
CasperJS 围绕步骤进行组织。使用此库,脚本通常如下所示:
casper.start('http://www.website.com/');
casper.then(function () {
// Step 1
});
casper.then(function () {
// Step 2
});
casper.then(function () {
// Step 3
});
casper.run();
then
方法不是承诺,但它们具有相同的目标:扁平化代码。因此,当你达到一定程度的嵌套时,你显然做错了。
evaluate
这种方法背后的概念可能是发现CasperJS时最难理解的。提醒一下,将evaluate()方法视为CasperJS环境与您打开的页面之间的门;每当你将一个闭包传递给evaluate()时,你就像进入浏览器控制台一样进入页面并执行代码。
在您的情况下,您在this.evaluate()
内使用thenEvaluate()
。我确信这不是你想做的......
this
并不总是您期望的如果我们考虑前两个点(嵌套和evaluate
),您似乎没有以正确的方式使用this
。当您在PhantomJS / CasperJS环境中时,this
是您的casper
实例。但在evaluate
内,您处于页面DOM环境中,这意味着this
变为window
。如果还不清楚,这是一个示例脚本:
var casper = require('casper').create();
casper.start('http://casperjs.org/');
casper.then(function () {
// "this" is "casper"
console.log(this.getCurrentUrl()); // http://casperjs.org/
});
casper.then(function () {
// "this" is "casper"
this.echo(this.evaluate(function () {
// "this" is "window"
return this.location.href; // http://casperjs.org/
}));
});
casper.run();
答案 1 :(得分:1)
您的代码中存在许多问题。与不将步骤(then*
和wait*
函数)匹配在一起意味着您将直接调用(casper.fill
)与步骤(thenEvaluate
)混合在一起。
另一个问题是,this
未在页面上下文(casper
和evaluate
内)引用thenEvaluate
。
这应该有效:
cityNames.forEach(function(cityName){
casper.then(function(){
this.fill('form.wpv-filter-form', { //setting drop-down field value to the city names in order of the items in the array
'city[]': cityName
});
});
casper.then(function(){
var regexString = '(\\?)(city)(\\[\\])(=)(' + cityName + ')&';
var regex = new RegExp(regexString, "igm");
this.waitForUrl(regex, function(){
var name = this.getHTML('.kw-details-title');
link = this.evaluate(getFirstItemLink); // for test, just getting the first item's link
this.thenOpen(link).then(function(){
this.echo("New Page is loaded......");
// Grab the single item contents
});
});
});
});