通过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!"; }