使用 CasperJS 中的函数返回 iframe 内的链接
Returning links inside iframe using a function in CasperJS
我正在尝试从 iframe 中获取链接并将它们 return 作为函数结果,我的简化代码如下所示:
var casper = require("casper").create({
verbose: true,
logLevel: "debug",
webSecurityEnabled: false
});
var url = casper.cli.get(0);
casper.on('remote.message', function(msg) {
this.echo(msg);
})
casper.start(url, function () {
thelinks = getLinksFromIframes( casper );
console.log("doesn't work:" + thelinks);
});
function getLinksFromIframes( context ) {
var links = [];
var iframes = context.evaluate( function() {
var iframes = [];
[].forEach.call(document.querySelectorAll("iframe"), function(iframe, i) { iframes.push( i ); });
return iframes;
});
iframes.forEach( function( index ) {
context.withFrame(index, function() {
links = links.concat( this.getElementsAttribute( 'a', 'href' ) );
console.log("works: " + links);
});
});
return links;
}
casper.run(function() {
console.log('done');
this.exit();
});
问题是该函数没有 return 任何东西,我只能读取 withFrame
中的链接 var,我知道还有其他方法可以获取链接,但代码是这种方式是因为它是分析嵌套 iframe 的更复杂事物的一部分,而 iframe 中的 iframe 数量是未知的。有什么方法可以让我等待 withFrame
或允许我 return 链接作为函数结果的方法吗?
这是预期的,因为 casper.withFrame
是一个异步步骤函数。与所有其他以 then
或 wait
开头的函数一样,它会在 CasperJS 执行队列中安排一个步骤。
当那些预定的步骤被执行时(在当前步骤的末尾,在你的例子中是 casper.start
的 then
回调),getLinksFromIframes
早已完成并返回空数组。
Is there any way I could wait on withIframe or something that will allow me to return the links as the function result?
否,但您可以使用回调:
function getLinksFromIframes( callback ) {
var links = [];
var iframes = this.evaluate( function() {
var iframes = [];
[].forEach.call(document.querySelectorAll("iframe"), function(iframe, i) { iframes.push( i ); });
return iframes;
});
iframes.forEach( function( index ) {
this.withFrame(index, function() {
links = links.concat( this.getElementsAttribute( 'a', 'href' ) );
console.log("works: " + links);
});
}, this);
this.then(function(){
callback.call(this, links);
});
}
casper.start(url, function () {
getLinksFromIframes.call(this, function(links){
thelinks = links;
console.log("Links: " + thelinks);
});
})
.then(function(){
console.log("Links later: " + thelinks);
})
.run();
我正在尝试从 iframe 中获取链接并将它们 return 作为函数结果,我的简化代码如下所示:
var casper = require("casper").create({
verbose: true,
logLevel: "debug",
webSecurityEnabled: false
});
var url = casper.cli.get(0);
casper.on('remote.message', function(msg) {
this.echo(msg);
})
casper.start(url, function () {
thelinks = getLinksFromIframes( casper );
console.log("doesn't work:" + thelinks);
});
function getLinksFromIframes( context ) {
var links = [];
var iframes = context.evaluate( function() {
var iframes = [];
[].forEach.call(document.querySelectorAll("iframe"), function(iframe, i) { iframes.push( i ); });
return iframes;
});
iframes.forEach( function( index ) {
context.withFrame(index, function() {
links = links.concat( this.getElementsAttribute( 'a', 'href' ) );
console.log("works: " + links);
});
});
return links;
}
casper.run(function() {
console.log('done');
this.exit();
});
问题是该函数没有 return 任何东西,我只能读取 withFrame
中的链接 var,我知道还有其他方法可以获取链接,但代码是这种方式是因为它是分析嵌套 iframe 的更复杂事物的一部分,而 iframe 中的 iframe 数量是未知的。有什么方法可以让我等待 withFrame
或允许我 return 链接作为函数结果的方法吗?
这是预期的,因为 casper.withFrame
是一个异步步骤函数。与所有其他以 then
或 wait
开头的函数一样,它会在 CasperJS 执行队列中安排一个步骤。
当那些预定的步骤被执行时(在当前步骤的末尾,在你的例子中是 casper.start
的 then
回调),getLinksFromIframes
早已完成并返回空数组。
Is there any way I could wait on withIframe or something that will allow me to return the links as the function result?
否,但您可以使用回调:
function getLinksFromIframes( callback ) {
var links = [];
var iframes = this.evaluate( function() {
var iframes = [];
[].forEach.call(document.querySelectorAll("iframe"), function(iframe, i) { iframes.push( i ); });
return iframes;
});
iframes.forEach( function( index ) {
this.withFrame(index, function() {
links = links.concat( this.getElementsAttribute( 'a', 'href' ) );
console.log("works: " + links);
});
}, this);
this.then(function(){
callback.call(this, links);
});
}
casper.start(url, function () {
getLinksFromIframes.call(this, function(links){
thelinks = links;
console.log("Links: " + thelinks);
});
})
.then(function(){
console.log("Links later: " + thelinks);
})
.run();