Pass arguments with page.evaluate

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., function() {
var foo = 42;

page.evaluate(function() {
// this code has no access to foo

How could I push arguments into the page?


Solution 1:

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:, function() {
  var foo = 42;

  evaluate(page, function(foo) {
    // this code has now has access to 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:
 * This is from comment #43.
function evaluate(page, func) {
    var args = [], 2);
    var fn = "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + ");}";
    return page.evaluate(fn);

Solution 2:

The change has been pushed and now you can use it as, function() {
  var foo = 42;

  page.evaluate( function(foo) {
  // this code has now has access to foo
  }, foo);

The push details are here:

Related:  how to stop Javascript forEach? [duplicate]

Solution 3:

There is the solution that works with PhantomJS 0.9.2 and 0.2.0:

    function (aa, bb) { document.title = aa + "/" + bb;}, //the function
    function (result) {}, // a callback when it's done
    "aaa", //attr 1
    "bbb"); //attr 2

Solution 4:

Another possibility: pass the variables in with the url. For example, to pass object 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);, function(status){
        // retrieve your var from document URL - if added with "&" this needs to change
        var x_json = decodeURIComponent(;
        // evil or not - eval is handy here
        var x = eval('(' + x_json + ')');       

Solution 5:

You can pass in the arguments to the function as arguments to page.evaluate.


page.evaluate(function(arg1, arg2){
    console.log(arg1); //Will print "hi"
    console.log(arg2); //Will print "there"
}, "hi", "there");

Solution 6:

This works for me:

page.evaluate("function() {document.body.innerHTML = '" + size + uid + "'}");

Means to put everything as a string. Anyway later it become a string. Check the library source.

Related:  Is there a way to tell knockout to wait to recalculate computed values until after the view model is defined?