我试图点击“下一个”按钮N次并每次抓取页面源。我知道我可以在远程网站上运行任意函数,所以我只使用远程函数nextPage()而不是click()我如何运行以下任意次数:
var casper = require('casper').create();
casper.start('http://www.example.com', function() {
this.echo(this.getHTML());
this.echo('-------------------------');
var numTimes = 4, count = 2;
casper.repeat(numTimes, function() {
this.thenEvaluate(function() {
nextPage(++count);
});
this.then(function() {
this.echo(this.getHTML());
this.echo('-------------------------');
});
});
});
'我'这是我尝试在javascript for循环中使用的索引。
所以tl;博士:我想舔'下一个',打印页面来源,点击'下一步',打印页面来源,点击'下一步'...继续N次。
答案 0 :(得分:7)
首先,您可以将值传递给远程页面上下文(即thenEvaluate
函数,如下所示:
this.thenEvaluate(function(remoteCount) {
nextPage(remoteCount);
}, ++count);
但是,Casper#repeat
可能不适合在此处使用,因为循环不会等待每个页面加载然后捕获内容。
您可能更愿意设计基于事件的链接。
代码的工作流程是:
拥有一个全局变量(或至少是下面提到的函数可访问的变量)来存储count
和limit
。
收听load.finished
事件并在此处抓取HTML,然后调用下一页。
简化代码可以是:
var casper = require('casper').create();
var limit = 5, count = 1;
casper.on('load.finished', function (status) {
if (status !== 'success') {
this.echo ("Failed to load page.");
}
else {
this.echo(this.getHTML());
this.echo('-------------------------');
}
if(++count > limit) {
this.echo ("Finished!");
}
else {
this.evaluate(function(remoteCount) {
nextPage(remoteCount);
// [Edit the line below was added later]
console.log(remoteCount);
return remoteCount;
}, count);
}
});
casper.start('http://www.example.com').run();
注意:如果您使用高负载的JS进程页面等,您可能还需要在调用nextPage之前添加
wait
:
this.wait(
1000, // in ms
function () {
this.evaluate(function(remoteCount) {
nextPage(remoteCount);
}, count);
}
);
[EDIT ADDED]以下事件监听器将帮助您进行调试。
// help is tracing page's console.log
casper.on('remote.message', function(msg) {
console.log('[Remote Page] ' + msg);
});
// Print out all the error messages from the web page
casper.on("page.error", function(msg, trace) {
casper.echo("[Remote Page Error] " + msg, "ERROR");
casper.echo("[Remote Error trace] " + JSON.stringify(trace, undefined, 4));
});
答案 1 :(得分:4)
您可以尝试使用Casper#repeat
在大多数情况下,这应该是你想要的:
var numTimes = 10, count = 1;
casper.repeat(numTimes, function() {
this.thenEvaluate(function(count) {
nextPage(count);
}, ++count);
this.then(function() {
this.echo(this.getHTML());
this.echo('-------------------------');
});
});
答案 2 :(得分:1)
var global_page_links = [];
casper.then(function(){
for(var i=1; i<=5; i++){
// you just add all your links to array, and use it in casper.each()
global_page_links.push(YOUR_LINK);
}
this.each(global_page_links, function(self, link) {
if (link){
self.thenOpen(link, function() {
console.log("OPENED: "+this.getCurrentUrl());
// do here what you need, evaluate() etc.
});
}
});
});
这是问题的答案,如何在casperjs中使用for()来启动多个链接