phantomjs可以使用node.js吗?
我想在我的node.js脚本中使用phantomjs。 有一个phantomjs节点库..但不幸的是作者使用这个怪异的咖啡脚本代码来解释他在做什么:
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()
现在如果我直接用javascript来使用phantomjs,它会看起来像这样 :
var page = require('webpage').create(); page.open(url, function (status) { var title = page.evaluate(function () { return document.title; }); console.log('Page title is ' + title); });
所以基本上我试图写在正常的JavaScript上面的代码的第一个片段的等效(通过阅读咖啡脚本文档 ..这是我做的:
// 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(); });
不幸的是它不工作! 如果我跑
node phantomTest.js
在壳上,什么也没有发生..没有任何回报,过程不停止..任何想法?
更新:
我刚刚在phantomjs faq上读到这个:
问:为什么PhantomJS不能写成Node.js模块?
答:简短的回答:“没有人可以服务两位大师。”
更长的解释如下。
到目前为止,这在技术上是非常具有挑战性的。
每个Node.js模块实质上是Node.js核心的“奴隶”,即“主”。 在当前状态下,PhantomJS(及其包含的WebKit)需要完全控制(同步)事件:事件循环,networking堆栈和JavaScript执行。
如果目的只是从Node.js中运行的脚本中使用PhantomJS,那么可以通过启动PhantomJS进程并与其进行交互来实现这种“松散绑定”。
嗯,这可能与它有什么关系? 但那整个图书馆就没有意义了!
更新2:
我在网上发现了这个代码,它做了同样的事情:
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(); }); }); }); });
不幸的是,这是行不通的结果!
phantomjs-node不是phantomjs官方支持的npm软件包。 相反,它通过创build一个使用websocket作为节点和幻像之间的IPC通道的Web服务器来实现节点和幻像之间的“恶心的巧妙桥梁”。 我没有这样做 :
所以我们通过启动一个ExpressJS的实例,在一个subprocess中打开Phantom,然后将它指向一个将socket.io消息转换为alert()调用的特殊网页来与PhantomJS进行通信。 那些alert()调用被Phantom拾起,你去了!
所以我不会感到惊讶,如果phantomjs节点工作,不工作,默默地失败,或失败壮观。 我也不希望除phantomjs-node的作者以外的任何人能够解决phantomjs-node问题。
你原来的问题的答案是从幻影常见问题的答案:不。幻影和节点有不可调和的分歧。 它们都希望完全控制事件循环,networking堆栈和JS执行等基本底层function,因此它们不能在同一个进程内合作。
你也可以尝试一下。 你的例子会写成这样:
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(); });
我现在是phantom-node
包的新维护者。 它不再使用coffeescript。 你可以做类似的事情
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(); }); }); }); });
新版本更快,更有弹性。 它也不再使用websockets。
改变你的代码,这将工作:
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(); }); }); }); });
你可以像我一样甩开PhantomJS,因为这些包装工作不好,太痛苦了,而且也是很受欢迎的Zombie.js 。
似乎这是工作..
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(); }); }); }); });
但我想用一些外部脚本文件生成一个html页面。 它无法注入脚本文件。 我尝试像下面。 callback不是从行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(); }); }); }); });
我遇到了同样的问题,显然, phantomjs-node
和phantomjs-node
更新版本存在已知问题 。 似乎它在节点0.9.3附近停止工作,根据问题的意见。 因此,在解决这个问题之前,您必须降级nodejs,或者尝试其他模块,比如node-phantom ,或者使用exec/spawn
。