遍历数组以尝试页面上的多个选项并返回到每次迭代的初始页面
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
函数不是 "finding" 浏览器上下文中的正确页面。我希望输出看起来像:
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
所以每次通过 this.each 都应该在第 2 步后导航回第一页。
单击提交按钮会导航到另一个页面,但问题似乎是您不再位于 eachThen
的下一次迭代的初始页面上:
So each pass through this.each should navigate back to the first page after step 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
实例。单击某些内容并创建新的 window/popup 时,可以创建其他页面实例,但这不是此处发生的情况。
你看到一个不同的短状态名称,但总是相同的长状态名称的原因是因为 states
在你开始迭代之前就已填充,但在第一次迭代后你继续在同一页面上.
您可能早先通过收听 "page.error" event 发现您的脚本存在问题,该 "page.error" event 会告诉您无法找到某些元素(在第一次迭代后 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);
。
我正在使用 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
函数不是 "finding" 浏览器上下文中的正确页面。我希望输出看起来像:
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
所以每次通过 this.each 都应该在第 2 步后导航回第一页。
单击提交按钮会导航到另一个页面,但问题似乎是您不再位于 eachThen
的下一次迭代的初始页面上:
So each pass through this.each should navigate back to the first page after step 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
实例。单击某些内容并创建新的 window/popup 时,可以创建其他页面实例,但这不是此处发生的情况。
你看到一个不同的短状态名称,但总是相同的长状态名称的原因是因为 states
在你开始迭代之前就已填充,但在第一次迭代后你继续在同一页面上.
您可能早先通过收听 "page.error" event 发现您的脚本存在问题,该 "page.error" event 会告诉您无法找到某些元素(在第一次迭代后 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);
。