Returning links inside iframe using a function in CasperJS

核能气质少年 提交于 2019-12-13 02:26:16

问题


I am trying to get the links from inside an iframe and return them as a function result, my simplified code looks something like this:

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

The problem is that the function doesn't return anything, I can only read the links var inside withFrame, i know there are other ways to get the links, but the code is this way because it part of something more complex that will analyze nested iframes, and the amount of iframes inside iframes is unknown. Is there any way I could wait on withFrame or something that will allow me to return the links as the function result?


回答1:


That's expected, because casper.withFrame is an asynchronous step function. Like all other functions that begin with either then or wait, it schedules a step in the CasperJS execution queue.

When those scheduled steps are executed (at the end of the current step, which is the then callback of casper.start in your case), getLinksFromIframes has long finished and returned an empty array.

Is there any way I could wait on withIframe or something that will allow me to return the links as the function result?

No, but you can use a callback:

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


来源:https://stackoverflow.com/questions/35672411/returning-links-inside-iframe-using-a-function-in-casperjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!