web-dev-qa-db-ja.com

ページのJavaScriptの実行後にページのHTML出力を保存する

スクレイプしようとしているサイトがあります。最初にhtml/jsを読み込み、jsを使用してフォーム入力フィールドを変更し、次にPOSTを使用します。 POSTされたページの最終的なHTML出力を取得するにはどうすればよいですか?

私はphantomjsでこれをやろうとしましたが、画像ファイルをレンダリングするオプションしか持っていないようです。周りをうろつくことはそれが可能であるべきであることを示唆します、しかし私はどのように理解することができません。私の試み:

var page = require('webpage').create();
var fs = require('fs');
page.open('https://www.somesite.com/page.aspx', function () {
    page.evaluate(function(){

    });

    page.render('export.png');
    fs.write('1.html', page.content, 'w');
    phantom.exit();
});

このコードはクライアントに使用されます。彼があまりにも多くのパッケージ(nodejs、casperjsなど)をインストールすることは期待できません。

ありがとう

49
gyaani_guy

持っている出力コードは正しいですが、同期性に問題があります。ページのロードが完了する前に、出力行が実行されています。 onLoadFinishedコールバックに結び付けて、いつ発生するかを調べることができます。以下の完全なコードを参照してください。

    var page = new WebPage()
    var fs = require('fs');

    page.onLoadFinished = function() {
      console.log("page load finished");
      page.render('export.png');
      fs.write('1.html', page.content, 'w');
      phantom.exit();
    };

    page.open("http://www.google.com", function() {
      page.evaluate(function() {
      });
    });

グーグルのようなサイトを使用する場合、ロードが非常に高速で、スクリーングラブをあなたが持っているようにインラインで実行できることが多いため、だまされる可能性があります。タイミングはphantomjsでは扱いにくいものです。タイミングが問題かどうかを確認するためにsetTimeoutでテストすることがあります。

26
uffa

コードを直接コピーし、URLをwww.google.comに変更すると、2つのファイルが保存された状態で正常に機能しました。

  • 1.html
  • export.png

ファイルは、.jsファイルが置かれている場所ではなく、スクリプトを実行した場所に書き込まれることに注意してください

4
Owen Martin

2日間の苦労と不満の末、ようやく同様の問題が解決しました。トリックを行ったのは、 waitfor.jsPhantomJSの公式Webサイト の例です。幸せになる!

"use strict";

function waitFor(testFx, onReady, timeOutMillis) {
    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
        start = new Date().getTime(),
        condition = false,
        interval = setInterval(function() {
            if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
                // If not time-out yet and condition not yet fulfilled
                condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
            } else {
                if(!condition) {
                    // If condition still not fulfilled (timeout but condition is 'false')
                    console.log("'waitFor()' timeout");
                    phantom.exit(1);
                } else {
                    // Condition fulfilled (timeout and/or condition is 'true')
                    console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
                    typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
                    clearInterval(interval); //< Stop this interval
                }
            }
        }, 250); //< repeat check every 250ms
};


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

// Open Twitter on 'sencha' profile and, onPageLoad, do...
page.open("http://Twitter.com/#!/sencha", function (status) {
    // Check for page load success
    if (status !== "success") {
        console.log("Unable to access network");
    } else {
        // Wait for 'signin-dropdown' to be visible
        waitFor(function() {
            // Check in the page if a specific element is now visible
            return page.evaluate(function() {
                return $("#signin-dropdown").is(":visible");
            });
        }, function() {
           console.log("The sign-in dialog should be visible now.");
           phantom.exit();
        });
    }
});
2
Heitor

CasperJS を使用して、PhantomJSでテストを実行しています。 tearDown 関数にこのコードを追加しました:

var require = patchRequire(require);
var fs = require('fs');

casper.test.begin("My Test", {
    tearDown: function(){
        casper.capture("export.png");
        fs.write("1.html", casper.getHTML(undefined, true), 'w');
    },
    test: function(test){
        // test code

        casper.run(function(){
            test.done();
        });
    }
});

capture および getHTML のドキュメントを参照してください。

0
Ben Hutchison

同様のタスクに対していくつかのアプローチを試し、Seleniumを使用して得た最良の結果を試しました。

PhantomJSと Cheerio を試す前に。 Phantomは、ページでJSを実行中に頻繁にクラッシュしていました。

0
strah