7

私のMacにHomebrew経由でインストールした後、Phantom.jsから始めたところです。

https://github.com/ariya/phantomjs/wiki/Quick-Startを介してWebサイトのスクリーンショットを保存するための例を試しています

var page = require('webpage').create();
page.open('http://google.com', function () {
    page.render('google.png');
    phantom.exit();
});

しかし、私はどこにも画像を見ていません。それらは.jsファイルと同じディレクトリにありますか?

4

7 に答える 7

9

PhantomJSは通常、実行しているスクリプトと同じディレクトリに画像をレンダリングします。そうです、PhantomJSを使用して実行しているJavaScriptファイルと同じディレクトリにある必要があります。

編集

その特定の例には欠陥があるようです。問題はpage.render(...);、ページのレンダリングに時間がかかることですが、phantom.exit()レンダリングが完了する前に呼び出しています。これを行うことで、期待される出力を得ることができました。

var page = require('webpage').create();
page.open('http://google.com', function () {
    page.render('google.png');
    setTimeout(function() { phantom.exit(); }, 5000) // wait five seconds and then exit;
});

残念ながら、これは理想的ではないので、私は髪の毛に良いものを思いつくことができました。基本的に、ページのレンダリングがいつ終了したかを確認するためにポーリングしているため、「髪の毛」と言います。

var done = false; //flag that tells us if we're done rendering

var page = require('webpage').create();
page.open('http://google.com', function (status) {
    //If the page loaded successfully...
    if(status === "success") {
        //Render the page
        page.render('google.png');
        console.log("Site rendered...");

        //Set the flag to true
        done = true;
    }
});

//Start polling every 100ms to see if we are done
var intervalId = setInterval(function() {
    if(done) {
        //If we are done, let's say so and exit.
        console.log("Done.");
        phantom.exit();
    } else {
        //If we're not done we're just going to say that we're polling
        console.log("Polling...");
    }
}, 100);

コールバックはすぐには実行されないため、上記のコードは機能します。したがって、ポーリングコードが起動し、ポーリングを開始します。次に、コールバックが実行されると、ページのステータスを確認します(ページを正常にロードできた場合にのみレンダリングします)。次に、ページをレンダリングし、ポーリングコードがチェックしているフラグをに設定しますtrue。したがって、次にポーリングコードが実行されるとき、フラグはtrueであるため、終了します。

これは、PhantomJSがwebpage#render(...)呼び出しを実行する方法に問題があるようです。ノンブロッキングコールだと思ったのですが、この号の作者によると、ブロッキングコールです。推測を危険にさらす必要がある場合、レンダリングの動作はブロッキング呼び出しである可能性がありますが、レンダリングを行うコードは、データをディスクに永続化することを処理する別のスレッドにデータを渡す可能性があります(したがって、この部分は-通話のブロック)。残念ながら、この呼び出しは、実行がメインスクリプトに戻って実行されたときにまだ実行されてphantom.exit()いる可能性があります。つまり、前述の非同期コードは、実行中の処理を終了する機会がありません。

PhantomJSフォーラムで、あなたが説明していることを扱った投稿を見つけることができました。提出された問題は見当たらないので、よろしければ投稿してください。

于 2013-03-04T16:12:14.200 に答える
8

私はこの投稿の作者とまったく同じ問題を抱えており、どのコード例も私にはうまくいきませんでした。Phantom.jsドキュメントの2番目の例が機能しないように混乱させるようなものです。SnowLeopardのHomeBrewを使用してインストールされます。

実例を見つけました

var page = require("webpage").create();
var homePage = "http://www.google.com/";
page.settings.javascriptEnabled = false;
page.settings.loadImages = false;
page.open(homePage);
page.onLoadFinished = function(status) {
  var url = page.url;
  console.log("Status:  " + status);
  console.log("Loaded:  " + url);
  page.render("google.png");
  phantom.exit();
};
于 2013-03-12T23:03:33.303 に答える
5

PhantomJSまたはCasperJSのスクリーンショットが保存されているディレクトリを探している人のための簡単なヘルプです。デフォルトではscriptsディレクトリにあります。ただし、あなたにはコントロールがあります。

保存場所を制御したい場合は、次のようにファイル名を変更できます。

page.render('screenshots/google.jpg'); // saves to scriptLocation/screenshots/
page.render('/opt/google.jpg'); // saves to /screenshots (in the root)

または、CasperJSを使用する場合は、次を使用できます。

casper.capture('/opt/google.jpg',
        undefined,
        { // imgOptions
            format: 'jpg',
            quality: 25
        }); 

これが誰かのトラブルを救うことを願っています!

于 2015-10-05T09:04:24.047 に答える
4

何かが変更されたかどうかはわかりませんが、http://phantomjs.org/screen-capture.htmlの例はうまくいきました。

var page = require('webpage').create();
page.open('http://github.com/', function() {
  page.render('github.png');
  phantom.exit();
});

phantomjs-2.1.1-windowsを実行しています。

しかし、私をこのスレッドに導いたのは、最初は、元の質問のようにイメージファイルがディスク上に作成されなかったことです。ある種のセキュリティの問題だと思ったので、VMにログインして、すべてを同じディレクトリに配置することから始めました。バッチファイルを使用して、パラメーターとして渡された.jsファイルを使用してphantomjs.exeを開始していました。すべてのファイルがVMの同じディレクトリにあるので、うまく機能しました。試行錯誤の結果、バッチファイルは.jsファイルと同じディレクトリにある必要があることがわかりました。これで、すべてが私のホストマシンでも正常に機能します。

要約すると...それはおそらく私にとってセキュリティ関連の問題でした。タイムアウトを追加する必要はありません。

元の質問に対する私の答えは、すべてが正しく設定されている場合、ファイルはphantomjs.exeが実行する.jsファイルと同じディレクトリにあるということです。画像ファイルの完全修飾パスを指定しようとしましたが、うまくいかなかったようです。

于 2016-07-27T20:16:22.747 に答える
1

根本的な原因は、onLoadFinished()イベント中であっても、page.render()が画像をレンダリングする準備ができていない可能性があることです。page.render()が成功するまでに、数秒以上待つ必要がある場合があります。PhantomJSで画像をレンダリングするために私が見つけた唯一の信頼できる方法は、メソッドがtrueを返し、画像が正常にレンダリングされたことを示すまで、page.render()を繰り返し呼び出すことです。

解決:

var page = require("webpage").create();
var homePage = "http://www.google.com/";

page.onLoadFinished = function(status) {
  var rendered, started = Date.now(), TIMEOUT = 30 * 1000; // 30 seconds
  while(!((rendered = page.render('google.png')) || Date.now() - started > TIMEOUT));
  if (!rendered) console.log("ERROR: Timed out waiting to render image.")
  phantom.exit();
};

page.open(homePage);
于 2014-11-26T20:34:57.820 に答える
0

ラスタライズ.jsの例から盗むと、受け入れられている答えよりも信頼性が高くなります。

var page = require('webpage').create();

page.open('http://localhost/TestForTest/', function (status) {
    console.log("starting...");
    console.log("Status: " + status);

    if (status === "success") {
        window.setTimeout(function () {
            page.render('myExample.png');
            phantom.exit();
        }, 200);
    } else {
        console.log("failed for some reason.");
    }
});
于 2016-01-15T09:21:05.390 に答える
0

ここにはたくさんの良い提案があります。追加したいことの1つ:

phantomjs dockerイメージを実行していましたが、デフォルトのユーザーはrootではなく「phantomjs」でした。したがって、許可されていない場所に書き込もうとしていました(Dockerホストのpwdでした)...

> docker run -i -t -v $(pwd):/pwd --rm wernight/phantomjs touch /pwd/foo.txt
touch: cannot touch '/pwd/foo.txt': Permission denied

上記のコードはすべてエラーなしで実行されますが、宛先に書き込む権限がない場合は、要求を黙って無視します...

したがって、たとえば、@ vivin-paliathのコード(現在受け入れられている回答)を取得すると、次のようになります。

var done = false; //flag that tells us if we're done rendering

var page = require('webpage').create();
page.open('http://google.com', function (status) {
    //If the page loaded successfully...
    if(status === "success") {
        //Render the page
        page.render('google.png');
        console.log("Site rendered...");

        //Set the flag to true
        done = true;
    }
});

//Start polling every 100ms to see if we are done
var intervalId = setInterval(function() {
    if(done) {
        //If we are done, let's say so and exit.
        console.log("Done.");
        phantom.exit();
    } else {
        //If we're not done we're just going to say that we're polling
        console.log("Polling...");
    }
}, 100);

そして、デフォルトのユーザーとしてそれを実行すると、次のようになります。

docker run -i -t -v $(pwd):/pwd -w /pwd --rm wernight/phantomjs phantomjs google.js 
Polling...
Polling...
Polling...
Polling...
Polling...
Polling...
Polling...
Polling...
Polling...
Polling...
Polling...
Polling...
Site rendered...
Done.

しかし、google.pngエラーはありません。-u rootdockerコマンドに追加するだけでこれが解決google.pngされ、CWDで取得できます。

完全を期すために、最後のコマンドは次のとおりです。

docker run -u root -i -t -v $(pwd):/ pwd -w / pwd --rm wernight / phantomjs phantomjs google.js

于 2017-04-28T20:54:51.250 に答える