通过page.evaluate传递参数
我正在使用PhantomJS page.evaluate()做一些刮擦。 我的问题是,我传递给webkit页面的代码是沙箱,所以没有访问我的主幻像脚本的variables。 这使得难以使通用的刮码。
page.open(url, function() { var foo = 42; page.evaluate(function() { // this code has no access to foo console.log(foo); }); }
我怎么能把参数推入页面?
我有这个确切的问题。 它可以做一些小小的诡计,因为page.evaluate
也可以接受一个string。
有几种方法可以做到这一点,但是我使用了一个名为evaluate
的包装,它接受附加parameter passing给必须在webkit端进行评估的函数。 你会这样使用它:
page.open(url, function() { var foo = 42; evaluate(page, function(foo) { // this code has now has access to foo console.log(foo); }, foo); });
这里是evaluate()
函数:
/* * This function wraps WebPage.evaluate, and offers the possibility to pass * parameters into the webpage function. The PhantomJS issue is here: * * http://code.google.com/p/phantomjs/issues/detail?id=132 * * This is from comment #43. */ function evaluate(page, func) { var args = [].slice.call(arguments, 2); var fn = "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + ");}"; return page.evaluate(fn); }
这个改变已经被推动了,现在你可以使用它了
page.open(url, function() { var foo = 42; page.evaluate( function(foo) { // this code has now has access to foo console.log(foo); }, foo); }
推的细节在这里: https : //github.com/ariya/phantomjs/commit/81794f9096
另一种可能性:将variables传递给url。 例如,要传递对象x
// turn your object "x" into a JSON string var x_json = JSON.stringify(x); // add to existing url // you might want to check for existing "?" and add with "&" url += '?' + encodeURIComponent(x_json); page.open(url, function(status){ page.evaluate(function(){ // retrieve your var from document URL - if added with "&" this needs to change var x_json = decodeURIComponent(window.location.search.substring(1)); // evil or not - eval is handy here var x = eval('(' + x_json + ')'); )} });
有PhantomJS 0.9.2和0.2.0的解决scheme:
page.evaluate( function (aa, bb) { document.title = aa + "/" + bb;}, //the function function (result) {}, // a callback when it's done "aaa", //attr 1 "bbb"); //attr 2
这适用于我:
page.evaluate("function() {document.body.innerHTML = '" + size + uid + "'}");
意味着把所有东西都当成一个string。 无论如何,它成为一个string。 检查图书馆的来源。
你不能只是将参数绑定到函数?
page.evaluate.bind(args)(callbackFn)
虽然可以将parameter passing给evaluate(function,arg1,arg2,…) ,但这通常会有点麻烦。 特别是在传递多个variables的情况下,或更糟糕的是,function。
为了解决这个障碍,可以使用injectJs(filename)来代替。
page.open(url, function() { if ( webpage.injectJs('my_extra_functionality.js') ) { page.evaluate( function() { // this code has access to foo and also myFunction(); console.log(foo); console.log(myFunction()); }); } else { console.log("Failed to inject JS"); } }
其中my_extra_functionality.js
是同一目录中的本地文件:
var foo = 42; var myFunction = function(){ return "Hello world!"; }