在数组上循环以尝试页面上的多个选项,并在每次迭代时返回到初始页面
Loop over an array to try multiple options on a page and come back to that initial page for each iteration
我正在使用CasperJS从网站上抓取一些数据。在主页上,有一个下拉列表,其中列出了所有50个州。该值是2个字母的缩写。
var states;
casper.start(url);
casper.then(function() {
states = this.evaluate(function getOptionVals() {
// loop thru and get the values
return arrayValues;
});
});
接下来,我想循环浏览缩写数组,然后在同一页上填充一些元素。页面上没有表单,只有一些单选按钮和一个提交按钮。
提交按钮导航到一个新的.asp页面,该页面将搜索选项作为查询字符串参数传递
casper.then(function () {
// loop over all states
this.eachThen(states,function(state) {
this.echo('state = ' + state.data);
// step 1
this.evaluate(function(state) {
console.log('In .evaluate the state is '+state);
// select the radio button
$('#searchoption1').prop('checked',true);
$('#searchoption2').prop('checked',false);
$('#showall').prop('checked',true);
// select the State from the dropdown
$('#state option[value="'+state+'"]').prop('selected', true);
$('#submit1').click();
},state.data); // pass in the array from the first casper.then call
// step 2
this.waitForSelector('table.mainTable tbody table tbody blockquote',function() {
this.evaluate(function(){
console.log($('table.mainTable h1 ').text());
});
});
})
});
casper.run();
我的问题是CasperJS的异步性。当我运行它时,console.log()
会报告每次通过循环时数组中第一个状态的结果。对于第2步,我尝试了很多不同的方法(来自SO上的帖子),但都无济于事。
如何让循环等待步骤2完成后再继续?
输出如下:
start step #1 get state abbreviations
start #2 loop over all states
state = AL
In .evaluate the state is AL
loc: (/Find_Range/wts_subresults_test.asp)
dir2: (e)
Ranges for the State/Province of Alabama
state = AK
In .evaluate the state is AK
Ranges for the State/Province of Alabama
state = AZ
In .evaluate the state is AZ
Ranges for the State/Province of Alabama
state = AR
In .evaluate the state is AR
Ranges for the State/Province of Alabama
state = CA
In .evaluate the state is CA
Ranges for the State/Province of Alabama
state = CO
In .evaluate the state is CO
Ranges for the State/Province of Alabama
state = CT
In .evaluate the state is CT
Ranges for the State/Province of Alabama
因此,this.evaluate
的this.waitForSelector
函数并不是在浏览器上下文中"找到"正确的页面。我希望输出看起来像:
In .evaluate the state is AL
loc: (/Find_Range/wts_subresults_test.asp)
dir2: (e)
Ranges for the State/Province of Alabama
state = AK
In .evaluate the state is AK
Ranges for the State/Province of Alaska
state = AZ
In .evaluate the state is AZ
Ranges for the State/Province of Arizona
state = AR
In .evaluate the state is AR
Ranges for the State/Province of Arkansas
state = CA
In .evaluate the state is CA
Ranges for the State/Province of California
state = CO
In .evaluate the state is CO
Ranges for the State/Province of colorado
所以每次通过这个。每个都应该导航回步骤2后的第一页。
单击提交按钮导航到另一个页面,但问题似乎是您在eachThen
的下一次迭代中不再处于初始页面:
因此,每次通过this.each都应该导航回步骤2之后的第一页。
此时您有两个选项:
1.在每次迭代中打开您开始时所在的页面:
casper.then(function () {
var url = this.getCurrentUrl();
// loop over all states
this.eachThen(states, function(state) {
this.echo('state = ' + state.data);
// step 0
this.thenOpen(url);
// step 1
this.thenEvaluate(...);
// step 2
this.waitForSelector(...);
})
});
注意,我使用了thenEvaluate
而不是evaluate
,因为像evaluate
这样的同步函数调用不应该跟在像thenOpen
这样的异步步进函数调用之后。
2.返回:
casper.then(function () {
// loop over all states
this.eachThen(states, function(state) {
this.echo('state = ' + state.data);
// step 1
this.thenEvaluate(...);
// step 2
this.waitForSelector(...);
// step 3
this.back();
})
});
请注意,您可能需要使用back
两次(或两次以上):this.back().back();
,因为有时会有重定向,PhantomJS不会在一步中进入预重定向页面。
如果您使用CasperJS进行导航,那么通常只有一个page
实例。当你点击某个东西并创建一个新的窗口/弹出窗口时,可以创建额外的页面实例,但这里不是这样。
您看到不同的短状态名称,但始终是相同的长状态名称的原因是,states
在您开始迭代之前就已填充,但在第一次迭代之后,您仍然在同一页上。
通过监听"page.error"事件,您可能已经注意到脚本的问题,该事件会向您显示无法找到某些元素(在第一次迭代后的evaluate
内部):
casper.on("page.error", function(msg, trace) {
this.echo("Error: " + msg);
// maybe make it a little fancier with the code from the PhantomJS equivalent
});
此外,如果你想知道发生了什么,你应该在每一个有趣的地方截屏casper.capture(filename);
- 迭代 JSON 文件并且未在 Javascript 中正确返回结果
- 在 es6 中迭代对象并返回新对象
- javascript中对数字数组的迭代返回字符串
- node.js for循环在函数调用返回之前进行迭代,从而产生对象问题
- 上次迭代返回未定义
- jquery map 数组在迭代器中返回 NaN
- 循环/迭代要返回的对象数组和字符串数组 - Javascript
- 迭代两个数组并执行 AND / OR 比较 = 返回 true
- 如何使用 React JS 迭代由 Java 休眠 DAO 返回的列表,该 DAO 在 UI 中以 this.state
- javascript 2D数组迭代返回未定义的函数参数
- 使用every()和其他迭代方法返回的次数
- 返回数组迭代
- text在迭代JavaScript XML中返回不需要的空文本值的内容
- 在AngularJS中使用ng repeat调用和迭代函数返回值
- React Render中的不变冲突或React中迭代和返回的正确方法
- second+迭代后没有返回值
- 为什么来自循环的警报总是返回最后一个值,而不是每个迭代值
- 在数组上循环以尝试页面上的多个选项,并在每次迭代时返回到初始页面
- 使用jquery对json进行迭代只返回第一个对象
- 迭代返回Generator的Generator