使用 CasperJS 中的函数返回 iframe 中的链接

Returning links inside iframe using a function in CasperJS

本文关键字:iframe 链接 返回 函数 使用 CasperJS      更新时间:2023-09-26

我正在尝试从 iframe 内部获取链接并将它们作为函数结果返回,我的简化代码如下所示:

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();
});

问题是该函数不返回任何内容,我只能读取withFrame内部的链接 var,我知道还有其他方法可以获取链接,但代码是这样的,因为它是更复杂的东西的一部分,将分析嵌套的 iframe,并且 iframe 内的 iframe 数量是未知的。有什么方法可以等待withFrame或允许我将链接作为函数结果返回的东西吗?

这是

意料之中的,因为casper.withFrame是一个异步步进函数。像所有其他以thenwait开头的函数一样,它在CasperJS执行队列中调度一个步骤。

当执行这些计划的步骤时(在当前步骤的末尾,在您的情况下是casper.startthen回调),getLinksFromIframes早已完成并返回一个空数组。

有什么方法可以等待Iframe或其他东西可以让我返回链接作为函数结果?

否,但您可以使用回调:

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();