Передайте аргументы со страницы.оценивать


Я использую страницу PhantomJS.оцените (), чтобы сделать некоторые выскабливание. Моя проблема заключается в том, что код, который я передаю на страницу webkit, изолирован и поэтому не имеет доступа к переменным моего основного фантомного скрипта. Это делает его трудно сделать выскабливание код универсальный.

page.open(url, function() {
  var foo = 42;

  page.evaluate(function() {
    // this code has no access to foo
    console.log(foo);
  });
}

Как я могу вставить аргументы на страницу?

8 53

8 ответов:

у меня была именно эта проблема. Это можно сделать с небольшим обманом, потому что page.evaluate также может принимать строку.

есть несколько способов сделать это, но я использую обертку под названием evaluate, который принимает дополнительные параметры для передачи функции, которая должна быть оценена на стороне 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

другая возможность: передайте переменные с 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:

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(arg1, arg2){
    console.log(arg1); //Will print "hi"
    console.log(arg2); //Will print "there"
}, "hi", "there");

это работает для меня:

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

означает поставить все как строку. Во всяком случае, позже это станет строкой. Проверьте источник библиотеки.

вы не можете просто привязать аргумента к функции??

page.evaluate.bind(args)(callbackFn)

в то время как вы можете передать аргументы в оценить (функция, arg1, arg2,...), это часто немного громоздким. Особенно в тех случаях, когда передается несколько переменных или, что еще хуже, функций.

чтобы обойти это препятствие, можно использовать 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!";
}