是否可以将函数传入casper.evaluate()?

时间:2015-09-24 15:02:55

标签: javascript function phantomjs casperjs

是否可以将函数传入casper.evaluate()

var casper = require('casper').create({
    //verbose: true,
    logLevel: 'debug',
    pageSettings: {
        loadImage: false,
        userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4'
    }
});    
...
casper.then(function(){
    var config = {};
    config.test = function(a, b){
       return a + b;
    }

    var extractInfo = this.evaluate(function(config) {
       return value = config.test(1, 2);
    }, config);
});

这不起作用,所以我假设没有,但似乎我们应该能够,因为我们可以传递像对象和数组中的其他东西。如果我可以附加函数来配置并传递,那将是CasperJS的巨大好处。

这样,在我运行scrape之前,辅助函数可以模块化并分成不同的包含等,使代码超级干净!

1 个答案:

答案 0 :(得分:2)

不,这不是直接可能的。 documentation说明如下:

  

注意: evaluate函数的参数和返回值必须是一个简单的原始对象。经验法则:如果它可以通过JSON序列化,那就没关系了。

     

闭包,函数,DOM节点等将工作!

单一功能

JavaScript当然是非常动态的,因此您可以序列化一个函数并将其作为字符串传递到页面上下文中。然后,您只需要在页面上下文中对其进行评估。

让我们以此为例(为简单起见)函数add

function add(a, b){
    return a + b;
}

您可以将其作为字符串传递到页面上下文中:

this.evaluate(function(addFun){
    // TODO: parse/evaluate function
}, add.toString());

new Function()

var addInternal = new Function("a", "b", addFun + "; return add(a, b);");

产生

var addInternal = function anonymous(a, b) {
function add(a, b){
    return a + b;
}; return add(a, b);
}

eval()

当然,简单地评估字符串会更容易。

eval(addFun)

直接生成add

也可以使用此技术评估闭包,但是您需要在eval时提供页面上下文内部范围的引用。

函数库

如果你想做更大的实用功能,我建议你研究一下CasperJS如何将clientutils.js包含在每一页(code)中。

通过将这些功能放在可以注入页面的附加文件中来完成。这可以使用casper.page.injectJs(filename)从本地文件同步执行,也可以使用casper.page.injectJs(filename, callback)从远程文件异步执行。

当然,CasperJS会提供设置,以便将这些设置注入casper.options.clientScriptscasper.options.remoteScripts的每个页面。