javascript - phantomjs node
¿Phantomjs puede trabajar con node.js? (7)
Ahora soy el nuevo mantenedor para el paquete phantom-node
. Ya no usa coffeescript. Puedes hacer algo como
var phantom = require(''phantom'');
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.open(''https://stackoverflow.com/'').then(function(status) {
console.log(status);
page.property(''content'').then(function(content) {
console.log(content);
page.close();
ph.exit();
});
});
});
});
La nueva versión es mucho más rápida y resistente. Tampoco usa websockets más.
Me gustaría usar phantomjs en mi script node.js. hay una biblioteca phantomjs-node ... pero desafortunadamente el autor usó este extraño código de script de café para explicar lo que está haciendo:
phantom = require ''phantom''
phantom.create (ph) ->
ph.createPage (page) ->
page.open "http://www.google.com", (status) ->
console.log "opened google? ", status
page.evaluate (-> document.title), (result) ->
console.log ''Page title is '' + result
ph.exit()
Ahora si tuviera que usar phantomjs directamente con javascript, se vería algo como this :
var page = require(''webpage'').create();
page.open(url, function (status) {
var title = page.evaluate(function () {
return document.title;
});
console.log(''Page title is '' + title);
});
así que básicamente estoy tratando de escribir el equivalente del primer fragmento de código anterior en javascript normal (leyendo la documentation script de café ... esto es lo que hice:
// file name: phantomTest.js
var phantom = require(''phantom'');
phantom.create(function(ph) {
ph.createPage(function(page) {
page.open(''http://www.google.com'', function(status) {
console.log(''opened google?'', status);
var title = page.evaluate(function() {
return document.title;
});
console.log(''page title is '' + title);
});
});
ph.exit();
});
¡Desafortunadamente no está funcionando! Si corro
node phantomTest.js
en la cáscara, no pasa nada ... nada vuelve y el proceso no se detiene ... ¿alguna idea?
actualizar:
Acabo de leer esto en las preguntas phantomjs:
P: ¿Por qué no se escribe PhantomJS como módulo Node.js?
A: La respuesta corta: "Nadie puede servir a dos maestros".
Una explicación más larga es la siguiente.
A partir de ahora, es técnicamente muy difícil hacerlo.
Cada módulo Node.js es esencialmente "un esclavo" del núcleo de Node.js, es decir, "el maestro". En su estado actual, PhantomJS (y su WebKit incluido) necesita tener el control total (en una materia síncrona) sobre todo: bucle de eventos, pila de red y ejecución de JavaScript.
Si la intención es simplemente usar PhantomJS directamente desde un script que se ejecuta dentro de Node.js, tal "enlace suelto" se puede lograr al iniciar un proceso PhantomJS e interactuar con él.
mmm .. esto podría tener algo que ver con eso? ¡Pero entonces toda la biblioteca no tendría sentido!
actualización 2:
Encontré este código en la web que hace lo mismo:
var phantom = require(''phantom'');
phantom.create(function(ph) {
return ph.createPage(function(page) {
return page.open("http://www.google.com", function(status) {
console.log("opened google? ", status);
return page.evaluate((function() {
return document.title;
}), function(result) {
console.log(''Page title is '' + result);
return ph.exit();
});
});
});
});
Desafortunadamente eso tampoco está funcionando ... ¡el mismo resultado!
Cambie su código a esto, y estará funcionando:
var phantom = require(''phantom'');
phantom.create(function(ph) {
ph.createPage(function(page) {
page.open("http://www.google.com", function(status) {
console.log("opened google? ", status);
page.evaluate((function() {
return document.title;
}), function(result) {
console.log(''Page title is '' + result);
ph.exit();
});
});
});
});
Experimenté los mismos problemas que usted, y aparentemente, hay un problema conocido con phantomjs-node
y versiones más recientes de nodejs. Parece que dejó de funcionar en algún lugar alrededor del nodo 0.9.3, de acuerdo con los comentarios del problema. Por lo tanto, hasta que esto se haya resuelto, debe degradar los nodejs o probar un módulo diferente, como node-phantom , o simplemente usar exec/spawn
.
Parece que esto está funcionando ...
var phantom = require(''phantom'');
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.open(''https://.com/'').then(function(status) {
console.log(status);
page.property(''content'').then(function(content) {
console.log(content);
page.close();
ph.exit();
});
});
});
});
Pero estoy tratando de generar una página html con algún archivo de script externo. No se puede inyectar un archivo de script. Intenté como seguir. La devolución de llamada no regresa de la línea page.injectJs(''./jQuery.min.js'',function() {
var phantom = require(''phantom'');
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.injectJs(''./jQuery.min.js'', function() {
page.property(''content'').then(function(content) {
console.log(content);
page.close();
ph.exit();
});
});
});
});
Podrías deshacerte de PhantomJS como lo hice porque era demasiado doloroso porque estas envolturas no funcionaban bien, e ir con Zombie.js que también es bastante popular.
También phridge darle una oportunidad a phridge . Tu ejemplo habría sido escrito así:
var phantom;
// spawn a new PhantomJS process
phridge.spawn()
.then(function (ph) {
phantom = ph;
return phantom.openPage("http://www.google.com");
})
.then(function (page) {
return page.run(function () {
// this function runs inside PhantomJS with this bound to a webpage instance
return this.title;
});
})
.then(function (title) {
console.log(''Page title is '' + title);
// terminates the process cleanly
phantom.dispose();
});
phantomjs-node no es un paquete npm compatible oficialmente para phantomjs. En su lugar, implementa un "puente ingeniosamente ingenioso" entre el nodo y el fantasma al crear un servidor web que utiliza websockets para servir como un canal de IPC entre el nodo y el fantasma. No estoy inventando esto
Así que nos comunicamos con PhantomJS girando una instancia de ExpressJS, abriendo Phantom en un subproceso, y apuntándolo a una página web especial que convierte los mensajes de socket.io en llamadas alert (). Esas llamadas de alerta () son recogidas por Phantom y ¡ahí lo tienes!
Por lo tanto, no me sorprendería si phantomjs-node funciona, no funciona, falla silenciosamente o falla espectacularmente. Tampoco esperaría que nadie más que el autor de phantomjs-node sea capaz de solucionar problemas de phantomjs-node.
La respuesta a su pregunta original es la respuesta de las preguntas phantomjs: No. Phantom y node tienen diferencias irreconciliables. Ambos esperan tener un control completo sobre la funcionalidad fundamental de bajo nivel, como el bucle de eventos, la pila de red y la ejecución de JS, por lo que no pueden cooperar en el mismo proceso.