phantomjs可以与node.js一起使用吗?

abb*_*ood 28 javascript jquery node.js coffeescript phantomjs

我想在我的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()
Run Code Online (Sandbox Code Playgroud)

现在如果我直接用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);
});
Run Code Online (Sandbox Code Playgroud)

所以基本上我正在尝试在普通的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();
});
Run Code Online (Sandbox Code Playgroud)

不幸的是它不起作用!如果我跑

node phantomTest.js
Run Code Online (Sandbox Code Playgroud)

在shell上,没有任何反应..没有任何回报,过程不会停止..任何想法?

更新:

我只是在phantomjs faq中读到这个:

问:为什么PhantomJS不能写成Node.js模块?

答:简短的回答是:"没有人能为两位大师服务."

更长的解释如下.

截至目前,这样做在技术上非常具有挑战性.

每个Node.js模块本质上是Node.js核心的"奴隶",即"主".在当前状态下,PhantomJS(及其包含的WebKit)需要对所有内容进行完全控制(在同步事物中):事件循环,网络堆栈和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();
      });
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

不幸的是,这也不起作用..同样的结果!

Rei*_*chs 39

phantomjs-node不是phantomjs官方支持的npm包.相反,它通过创建一个使用websockets作为节点和幻像之间的IPC通道的Web服务器,在节点和幻像之间实现了"令人作呕的聪明桥梁".我不是这样说的:

因此,我们通过启动ExpressJS实例与PhantomJS进行通信,在子进程中打开Phantom,并将其指向一个特殊的网页,将socket.io消息转换为alert()调用.那些alert()调用是由Phantom接收的,你去了!

如果phantomjs-node工作,不工作,无声失败或失败,我不会感到惊讶.我也不希望除了phantomjs-node的作者之外的任何人能够对phantomjs-node进行故障排除.

你原来的问题的答案是phantomjs faq的答案:不.幻影和节点有不可调和的差异.两者都希望完全控制基本的低级功能,如事件循环,网络堆栈和JS执行,这样他们就无法在同一个进程中进行协作.

  • 哇,这太讨厌了!接下来的问题是:使用jquery抓取动态页面的最佳方法是什么? (5认同)

Joh*_*ald 9

你也可以给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();
    });
Run Code Online (Sandbox Code Playgroud)


Ami*_*far 9

我现在是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();
      });
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

新版本更快更有弹性.它也不再使用websockets.