jQuery phantomjs 可以与 node.js 一起使用吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15745394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
can phantomjs work with node.js?
提问by abbood
I would like to use phantomjs in my node.js script. there is a phantomjs-nodelibrary.. but unfortunately the author used this weird coffee script code to explain what he's doing:
我想在我的 node.js 脚本中使用 phantomjs。有一个phantomjs-node库..但不幸的是,作者使用这个奇怪的咖啡脚本代码来解释他在做什么:
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:
现在,如果我直接在 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);
});
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:
所以基本上我试图在普通的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();
});
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:
我刚刚在 phantomjs常见问题解答中读到了这个:
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.
问:为什么 PhantomJS 没有写成 Node.js 模块?
答:简答:“没有人可以侍奉两个主人。”
更长的解释如下。
截至目前,这样做在技术上非常具有挑战性。
每个 Node.js 模块本质上都是 Node.js 核心的“奴隶”,即“主人”。在当前状态下,PhantomJS(及其包含的 WebKit)需要完全控制(以同步方式)一切:事件循环、网络堆栈和 JavaScript 执行。
如果目的只是直接从 Node.js 中运行的脚本中使用 PhantomJS,那么可以通过启动 PhantomJS 进程并与之交互来实现这种“松散绑定”。
mmm.. could this have something to do with it? but then that whole library wouldn't make sense!
嗯..这可能与它有关吗?但那样整个图书馆就没有意义了!
update 2:
更新2:
I found this code in the webthat 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!
不幸的是,这也不起作用……同样的结果!
回答by Rein Henrichs
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:
phantomjs-node 不是 phantomjs 官方支持的 npm 包。相反,它通过创建一个使用 websockets 作为节点和幻像之间的 IPC 通道的 Web 服务器,在节点和幻像之间实现了一个“令人作呕的聪明桥梁”。我不是在编造这个:
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!
因此,我们通过启动 ExpressJS 的一个实例,在子进程中打开 Phantom,并将其指向一个将 socket.io 消息转换为 alert() 调用的特殊网页来与 PhantomJS 进行通信。那些 alert() 调用由 Phantom 接收,然后就可以了!
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.
因此,如果 phantomjs-node 工作、不工作、无声地失败或严重失败,我不会感到惊讶。我也不希望 phantomjs-node 的作者以外的任何人能够对 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.
你原来问题的答案是来自phantomjs faq的答案:不。Phantom和node有不可调和的差异。两者都希望完全控制基本的低级功能,例如事件循环、网络堆栈和 JS 执行,因此它们无法在同一个进程中进行协作。
回答by Johannes Ewald
You could also give phridgea try. Your example would've been written like this:
你也可以试试phridge。你的例子应该是这样写的:
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();
});
回答by Amir Raminfar
I am now the new maintainer for phantom-node
package. It doesn't use coffeescript anymore. You can do something like
我现在是phantom-node
package的新维护者。它不再使用咖啡脚本了。你可以做类似的事情
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();
});
});
});
});
The new version is much faster and resilient. It also doesn't use websockets anymore.
新版本的速度和弹性要快得多。它也不再使用 websockets。
回答by Vishnu
Seems this is working..
似乎这是有效的..
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();
});
});
});
});
But I am trying to generate an html page with some external script file. It is unable to inject a script file. I tried like following. Callback is not returning from the line page.injectJs('./jQuery.min.js',function() {
但我试图用一些外部脚本文件生成一个 html 页面。无法注入脚本文件。我试过如下。回调未从线路返回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();
});
});
});
});
回答by PositiveGuy
回答by Billy Shea
change your code to this, and it will be working:
将您的代码更改为此,它将起作用:
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();
});
});
});
});
回答by NilsH
I experienced the same problems as you do, and apparently, there is a known issuewith phantomjs-node
and newer versions of nodejs. Seems like it stopped working somewhere around node 0.9.3, according to the comments in the issue. So until that has been resolved, you either have to downgrade nodejs, or try a different module, like node-phantom, or just use exec/spawn
.
我遇到了同样的问题,你这样做,显然,有一个已知的问题,与phantomjs-node
和的NodeJS的新版本。根据问题中的评论,它似乎在节点 0.9.3 附近的某个地方停止工作。因此,在解决此问题之前,您要么必须降级 nodejs,要么尝试不同的模块,例如node-phantom,或者只使用exec/spawn
.