Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass arguments with page.evaluate

I'm using PhantomJS page.evaluate() to do some scraping. My problem is that the code I pass to the webkit page is sandboxed, and so has no access to the variables of my main phantom script. This makes it hard make the scraping code generic.

page.open(url, function() {   var foo = 42;    page.evaluate(function() {     // this code has no access to foo     console.log(foo);   }); } 

How could I push arguments into the page?

like image 475
TheFist Avatar asked Mar 23 '12 11:03

TheFist


People also ask

How do you pass a function in page to evaluate?

You cannot pass a function directly into page. evaluate() , but you can call another special method ( page. exposeFunction ), which expose your function as a global function (also available in as an attribute of your page window object), so you can call it when you are inside page.

What does Page evaluate mean?

evaluate() method. Evaluates a function in the page's context and returns the result. If the function passed to page. evaluteHandle returns a Promise, the function will wait for the promise to resolve and return its value.


1 Answers

I've had that exact problem. It can be done with a little trickery, because page.evaluate also can accept a string.

There are several ways to do it, but I use a wrapper called evaluate, which accepts additional parameters to pass to the function that must be evaluated on the webkit side. You would use it like this:

page.open(url, function() {   var foo = 42;    evaluate(page, function(foo) {     // this code has now has access to foo     console.log(foo);   }, foo); }); 

And here is the evaluate() function:

/*  * 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); } 
like image 64
Weston Avatar answered Sep 25 '22 12:09

Weston