Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can phantomjs work with node.js?

I would like to use phantomjs in my node.js script. there is a phantomjs-node library.. but unfortunately the author used this weird coffee script code to explain what he's doing:

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() 

now if I were to use phantomjs directly with javascript, it would look something like 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); }); 

so basically I'm trying to write up the equivalent of the first snippet of code above in normal javascript (by reading the coffee script documentation.. this is what I did:

// 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(); }); 

unfortunately it's not working! If I run

node phantomTest.js 

on the shell, nothing happens.. nothing returns and the process doesn't stop.. any ideas?

update:

I just read this in the phantomjs faq:

Q: Why is PhantomJS not written as Node.js module?

A: The short answer: "No one can serve two masters."

A longer explanation is as follows.

As of now, it is technically very challenging to do so.

Every Node.js module is essentially "a slave" to the core of Node.js, i.e. "the master". In its current state, PhantomJS (and its included WebKit) needs to have the full control (in a synchronous matter) over everything: event loop, network stack, and JavaScript execution.

If the intention is just about using PhantomJS right from a script running within Node.js, such a "loose binding" can be achieved by launching a PhantomJS process and interact with it.

mmm.. could this have something to do with it? but then that whole library wouldn't make sense!

update 2:

I found this code in the web that does the same thing:

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

unfortunately that's not working either.. same result!

like image 947
abbood Avatar asked Apr 01 '13 14:04

abbood


People also ask

How do I run PhantomJS?

Go to the “bin” folder and check phantomjs.exe file. If you are using it on a Windows OS, then you can set the path variable under the environment variable for fast access through command prompt. The command to run the PhantomJS program: C:\> phantomjs [options] file.

Can NodeJs used in browser?

js is a server-side JavaScript run-time environment. It's open-source, including Google's V8 engine, libuv for cross-platform compatibility, and a core library. Notably, Node. js does not expose a global "window" object, since it does not run within a browser.

Can I use node js in JavaScript?

Node. js allows you to run JavaScript on the server.


2 Answers

phantomjs-node isn't an official supported npm package for phantomjs. Instead, it implements a "nauseously clever bridge" between node and phantom by creating a web server that uses websockets to serve as an IPC channel between node and phantom. I'm not making this up:

So we communicate with PhantomJS by spinning up an instance of ExpressJS, opening Phantom in a subprocess, and pointing it at a special webpage that turns socket.io messages into alert() calls. Those alert() calls are picked up by Phantom and there you go!

So I wouldn't be surprised if phantomjs-node works, doesn't work, fails silently, or fails spectacularly. Nor would I expect anyone other than the author of phantomjs-node to be able to troubleshoot phantomjs-node.

The answer to your original question is the answer from the phantomjs faq: No. Phantom and node have irreconcilable differences. Both expect to have complete control over fundamental low-level functionality like the event loop, the network stack, and JS execution so they can't cooperate within the same process.

like image 130
Rein Henrichs Avatar answered Sep 23 '22 00:09

Rein Henrichs


You could also give phridge a try. Your example would've been written like this:

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();     }); 
like image 22
Johannes Ewald Avatar answered Sep 23 '22 00:09

Johannes Ewald