Javascript phantomjs可以与node.js一起工作吗?
我想在node.js脚本中使用phantomjs。有一个图书馆。。但不幸的是,作者用这个奇怪的咖啡脚本代码来解释他在做什么:Javascript phantomjs可以与node.js一起工作吗?,javascript,jquery,node.js,coffeescript,phantomjs,Javascript,Jquery,Node.js,Coffeescript,Phantomjs,我想在node.js脚本中使用phantomjs。有一个图书馆。。但不幸的是,作者用这个奇怪的咖啡脚本代码来解释他在做什么: phantom = require 'phantom' phantom.create (ph) -> ph.createPage (page) -> page.open "http://www.google.com", (status) -> console.log "opened google? ", status
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()
现在,如果我将phantomjs直接与javascript一起使用,它看起来会像:
因此,基本上我正在尝试用普通javascript编写与上面的第一段代码等效的代码(通过阅读coffee脚本)。这就是我所做的:
// 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不作为Node.js模块编写
答:简短的回答是:“没有人能为两个主人服务。”
一个较长的解释如下
到目前为止,这样做在技术上非常具有挑战性
每个Node.js模块本质上都是Node.js核心的“从机”,
i、 在其当前状态下,PhantomJS(及其包含的
WebKit)需要(在同步事务中)完全控制
一切:事件循环、网络堆栈和JavaScript执行
如果目的仅仅是从脚本中使用PhantomJS
在Node.js中运行,这种“松散绑定”可以通过以下方式实现
启动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节点不是官方支持的phantomjs npm包。相反,它通过创建一个web服务器,使用WebSocket作为节点和phantomjs之间的IPC通道,在节点和phantomjs之间实现了一个“令人恶心的智能桥梁” 因此,我们通过旋转ExpressJS的一个实例来与PhantomJS通信,在子流程中打开Phantom,并将其指向一个特殊的网页,该网页将socket.io消息转换为alert()调用 因此,如果phantomjs节点工作、不工作、无声地失败或异常地失败,我不会感到惊讶。我也不希望phantomjs节点的作者以外的任何人能够对phantomjs节点进行故障排除
原始问题的答案是phantomjs faq中的答案:否。phantomjs和node有不可调和的差异。两者都希望能够完全控制基本的低级功能,如事件循环、网络堆栈和JS执行,因此它们不能在同一个过程中协作。我也遇到过同样的问题正如你所做的,显然,有一个带有
phantomjs节点
和更新版本的nodejs。根据问题中的评论,它似乎在节点0.9.3附近停止工作。因此,在解决这个问题之前,你要么降级nodejs,要么尝试其他模块,比如,或者只使用exec/spawn
> 将代码更改为此,它将正常工作:
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();
});
});
});
});
您也可以试一试。您的示例应该是这样写的:
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,因为这些包装不太好让人痛苦,而且它也很流行。我现在是
PhantomNode
包的新维护者。它不再使用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();
});
});
});
});
新版本速度更快,弹性更强。它也不再使用WebSocket了。这似乎是可行的
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页面。它无法插入脚本文件。我尝试了以下方法。回调不会从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();
});
});
});
});
哇,这太糟糕了!那么接下来的问题是:使用jquery抓取动态页面的最佳方式是什么?@abbood我认为这是不可能的。你的目标是什么?为什么不可能?我想我找到了我的想法……一如既往……我从走一条不可能的艰难路线开始,只是为了找到一个更简单的解决方案,哈哈……我会给你正确的答案回答奖励..如果你在jQuery中插入一个完整的DOM和JS运行时实现,这是可能的,但我认为这不是一个可行的解决方案。是的!它现在对我来说很有吸引力..只需将原始html转储到DOM结构中..使用jQuery魔法遍历它..大家都很高兴!看看我对m(上面的y问题;)称某事为“愚蠢”因为你不了解它是如何工作的和/或你不能让它在你的情况下工作,这是非常粗鲁的。另外,还有一个比其他Node.js桥更推荐的桥。人们一直在使用Ruby、PHP、Node.js桥接PhantomJS,并取得了不同的成功。我为我的强硬措辞道歉,我将从问题中删除它。我还将接受一个l看看
phantom proxy
。最后,我的目标是让事情顺利进行,而不是贬低他人的努力。这已经过时,应该编辑或删除。它没有反映最新的phantomjs节点包及其功能。
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();
});
});
});
});