web-dev-qa-db-ja.com

phantomjsはnode.jsで動作しますか?

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

phantomjsをjavascriptで直接使用すると、 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);
});

だから基本的に私は通常のjavascriptで上記のコードの最初のスニペットに相当するものを書き込もうとしています(コーヒースクリプトを読むことで documentation ..これは私がやったことです:

// 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

シェルでは、何も起こりません。何も戻りません。プロセスは停止しません。

update:

私はこれをphantomjsで読みました faq

Q:PhantomJSがNode.jsモジュールとして記述されていないのはなぜですか?

A:短い答え:「だれも2人のマスターに仕えることはできません。」

より長い説明は次のとおりです。

今のところ、そうすることは技術的に非常に困難です。

すべてのNode.jsモジュールは、本質的にNode.jsのコアの「スレーブ」、つまり「マスター」です。現在の状態では、PhantomJS(および同梱されているWebKit)は、イベントループ、ネットワークスタック、JavaScript実行など、すべてを(同期的に)完全に制御する必要があります。

Node.js内で実行されているスクリプトからPhantomJSを使用することだけが目的の場合、PhantomJSプロセスを起動して対話することで、このような「緩いバインディング」を実現できます。

mmm ..これは何か関係があるのでしょうか?しかし、そのライブラリ全体は意味をなさないでしょう!

更新2:

web で同じコードを見つけました:

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

残念ながらそれも機能していません。同じ結果です!

28
abbood

phantomjs-nodeは、phantomjs用に公式にサポートされているnpmパッケージではありません。代わりに、websocketを使用してノードとファントム間のIPCチャネルとして機能するWebサーバーを作成することにより、ノードとファントム間の「悪意のある巧妙なブリッジ」を実装します。 私はそうではありませんこれを構成する

そのため、ExpressJSのインスタンスをスピンアップし、Phantomをサブプロセスで開き、socket.ioメッセージをalert()呼び出しに変換する特別なWebページを指すことにより、PhantomJSと通信します。これらのalert()呼び出しはPhantomによってピックアップされ、そこに行きます!

そのため、phantomjs-nodeが機能する、機能しない、静かに失敗する、または見事に失敗する場合でも、私は驚かないでしょう。また、phantomjs-nodeの作成者以外の人がphantomjs-nodeのトラブルシューティングを行えるとは期待していません。

元の質問に対する答えは、phantomjsのFAQからの答えです。いいえ。Phantomとnodeには調整不可能な違いがあります。どちらも、イベントループ、ネットワークスタック、JS実行などの基本的な低レベル機能を完全に制御できるため、同じプロセス内で連携することはできません。

39
Rein Henrichs

私はphantom-nodeパッケージの新しいメンテナーになりました。コーヒースクリプトはもう使用しません。次のようなことができます

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を使用しなくなりました。

9
Amir Raminfar

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

これらのラッパーがうまく機能せず、あまりにも苦痛だったので、私と同じようにPhantomJSを捨てることができ、 Zombie.js で行くことができます人気も。

1
PositiveGuy

コードをこれに変更すると、動作します:

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

これは機能しているようです。

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

私はあなたと同じ問題を経験しましたが、明らかに、phantomjs-nodeおよびnodejsの新しいバージョンには 既知の問題 があります。問題のコメントによると、ノード0.9.3付近で動作しなくなったようです。したがって、それが解決されるまで、nodejsをダウングレードするか、 node-phantom のような別のモジュールを試すか、単にexec/spawnを使用する必要があります。

0
NilsH