tutorial phantom node example alternative javascript phantomjs

javascript - phantom - Pasar argumentos con page.evaluate



phantomjs pdf (8)

¿No puedes unir los argumentos a la función?

page.evaluate.bind(args)(callbackFn)

Estoy usando PhantomJS page.evaluate () para hacer un poco de raspado. Mi problema es que el código que paso a la página de webkit es sandbox, y por lo tanto no tiene acceso a las variables de mi script fantasma principal. Esto hace que sea difícil hacer genérico el código de raspado.

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

¿Cómo podría enviar argumentos a la página?


El cambio ha sido empujado y ahora puedes usarlo como

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

Los detalles de inserción están aquí: https://github.com/ariya/phantomjs/commit/81794f9096


Esto funciona para mí:

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

Significa poner todo como una cadena. De todos modos, luego se convierte en una cadena. Verifique la fuente de la biblioteca.


Existe la solución que funciona con PhantomJS 0.9.2 y 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


He tenido ese problema exacto. Se puede hacer con un pequeño truco, porque page.evaluate también puede aceptar una cadena.

Hay varias maneras de hacerlo, pero utilizo un contenedor llamado evaluate , que acepta parámetros adicionales para pasar a la función que debe evaluarse en el lado del webkit. Lo usarías así:

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

Y aquí está la función de 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); }


Otra posibilidad: pasar las variables con la url. Por ejemplo, para pasar el objeto 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 + '')''); )} });


Puede pasar los argumentos a la función como argumentos para page.evaluate.

Ejemplo:

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


Si bien puede pasar argumentos a evaluar (función, arg1, arg2, ...) , esto suele ser un poco engorroso. Especialmente en casos cuando se pasan varias variables, o peor, funciones.

Para evitar este obstáculo, uno puede usar injectJs(filename) lugar.

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"); } }

Donde my_extra_functionality.js es un archivo local en el mismo directorio:

var foo = 42; var myFunction = function(){ return "Hello world!"; }