是否可以将函数传入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之前,辅助函数可以模块化并分成不同的包含等,使代码超级干净!
答案 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());
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(addFun)
直接生成add
。
也可以使用此技术评估闭包,但是您需要在eval
时提供页面上下文内部范围的引用。
如果你想做更大的实用功能,我建议你研究一下CasperJS如何将clientutils.js包含在每一页(code)中。
通过将这些功能放在可以注入页面的附加文件中来完成。这可以使用casper.page.injectJs(filename)
从本地文件同步执行,也可以使用casper.page.injectJs(filename, callback)
从远程文件异步执行。
当然,CasperJS会提供设置,以便将这些设置注入casper.options.clientScripts
或casper.options.remoteScripts
的每个页面。