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