web-dev-qa-db-ja.com

続行する前にclick()イベントがphantomjsに読み込まれるのを待つ方法は?

Phantomjsには、これらの2つの非常に便利なコールバックonLoadStartedonLoadFinishedがあり、ページのロード中に実行を本質的に一時停止できます。しかし、私は検索してきましたが、送信ボタンまたはハイパーリンクをclick()した場合に相当するものを見つけることができません。同様のページの読み込みが発生しますが、このイベントではonLoadStartedが呼び出されません。発生する明示的なpage.open()がないためです。この負荷が発生している間、実行を一時停止するためのクリーンな方法を見つけようとしています。

1つの解決策は明らかにsetTimeoutの入れ子ですが、何かをテストしたりイベントを待機したりするような、信頼性が高くより堅牢なものではなく、やりがいがあり試行錯誤に依存しているため、このシナリオは避けたいと思います。

私が見逃した、この種のページロードに対する特定のコールバックはありますか?それとも、この種のことを処理できる一般的なコードパターンがあるのでしょうか。

編集:

それを一時停止させる方法はまだわかりません。 onLoadStarted()コマンドを呼び出すときにclick()関数を呼び出さないコードは次のとおりです。

_var loadInProgress = false;

page.onLoadStarted = function() {
  loadInProgress = true;
  console.log("load started");
};

page.onLoadFinished = function() {
  loadInProgress = false;
  console.log("load finished");
};

page.open(loginPage.url, function (status) {
    if (status !== 'success') {
        console.log('Unable to access network');
        fs.write(filePath + errorState, 1, 'w');
        phantom.exit();
    } else {
        page.evaluate(function (loginPage, credentials) {
            console.log('inside loginPage evaluate function...\n')
            document.querySelector('input[id=' + loginPage.userId + ']').value = credentials.username;
            document.querySelector('input[id=' + loginPage.passId + ']').value = credentials.password;      
            document.querySelector('input[id=' + loginPage.submitId + ']').click();
            //var aTags = document.getElementsByTagName('a')
            //aTags[1].click();
        }, loginPage, credentials);

        page.render(renderPath + 'postLogin.png');
        console.log('rendered post-login');
_

IDが正しいことを再確認しました。 page.render()は、情報が送信されたことを示しますが、それがsetTimeout()に入れられた場合にのみ、そうでない場合はすぐにレンダリングされ、ページリダイレクトの前に入力された資格情報のみが表示されます。多分私は何か他に欠けていますか?

17
Jpaji Rajnish

onLoadStarted関数とonLoadFinished関数が必要なものだと思います。たとえば、次のスクリプトを見てください。

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

page.onResourceReceived = function(response) {
    if (response.stage !== "end") return;
    console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + response.url);
};
page.onResourceRequested = function(requestData, networkRequest) {
    console.log('Request (#' + requestData.id + '): ' + requestData.url);
};
page.onUrlChanged = function(targetUrl) {
    console.log('New URL: ' + targetUrl);
};
page.onLoadFinished = function(status) {
    console.log('Load Finished: ' + status);
};
page.onLoadStarted = function() {
    console.log('Load Started');
};
page.onNavigationRequested = function(url, type, willNavigate, main) {
    console.log('Trying to navigate to: ' + url);
};

page.open("http://example.com", function(status){
    page.evaluate(function(){
        // click
        var e = document.createEvent('MouseEvents');
        e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        document.querySelector("a").dispatchEvent(e);
    });
    setTimeout(function(){
        phantom.exit();
    }, 10000);
});

印刷する

移動しようとしています:http://example.com/
リクエスト(#1):http://example.com/
ロードが開始されました
新規URL:http://example.com/
応答(#1、ステージ「終了」):http://example.com/
読み込み完了:成功
しようとしています次の場所に移動します:http://www.iana.org/domains/example
リクエスト(#2):http://www.iana.org/domains/example
読み込み開始
移動先:http://www.iana.org/domains/reserved
リクエスト(#3):http://www.iana.org/domains/reserved
Response (#2、ステージ「終了」):http://www.iana.org/domains/example
新しいURL:http://www.iana.org/domains/reserved
リクエスト(#4):http://www.iana.org/_css/2013.1/screen.css
リクエスト(#5):http://www.iana.org/_js/2013.1/jquery.js 
リクエスト(#6):http://www.iana.org/_js/2013.1/iana.js
レスポンス(#3、ステージ「終了」):http:// www。 iana.org/domains/reserved
Response(#6、stage "end"):http://www.iana.org/_js/2013.1/iana.js
Response(#4、ステージ「終了」):http:// w ww.iana.org/_css/2013.1/screen.css
応答(#5、ステージ "end"):http://www.iana.org/_js/2013.1/jquery.js
リクエスト(#7):http://www.iana.org/_img/2013.1/iana-logo-header.svg
リクエスト(#8):http://www.iana.org/_img /2013.1/icann-logo.svg
Response(#8、stage "end"):http://www.iana.org/_img/2013.1/icann-logo.svg
Response( #7、ステージ「終了」):http://www.iana.org/_img/2013.1/iana-logo-header.svg
リクエスト(#9):http://www.iana.org /_css/2013.1/print.css
応答(#9、ステージ「終了」):http://www.iana.org/_css/2013.1/print.css
読み込み完了:成功

リダイレクトがあるため、リンクをクリックすると、LoadStartedイベントが1回、NavigationRequestedイベントが2回発行されることを示しています。トリックは、アクションを実行する前にイベントハンドラーを追加することです。

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

page.open("http://example.com", function(status){
    page.onLoadFinished = function(status) {
        console.log('Load Finished: ' + status);
        page.render("test37_next_page.png");
        phantom.exit();
    };
    page.onLoadStarted = function() {
        console.log('Load Started');
    };

    page.evaluate(function(){
        var e = document.createEvent('MouseEvents');
        e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        document.querySelector("a").dispatchEvent(e);
    });
});

これらのことを行う必要がある場合は、おそらく CasperJS のような他のことを試す時です。 PhantomJSの上で実行されますが、WebページをナビゲートするためのAPIがはるかに優れています。

13
Artjom B.

高レベルのラッパー nightmarejs を使用します。そこで簡単にclickして、後で待つことができます。

これがコードです(例のセクション):

var Nightmare = require('nightmare');
new Nightmare()
  .goto('http://yahoo.com')
    .type('input[title="Search"]', 'github nightmare')
    .click('.searchsubmit')
    .run(function (err, nightmare) {
      if (err) return console.log(err);
      console.log('Done!');
    });

その他の例とAPIの使用法は github にあります

8

これが他のいくつかの回答に基づく私のコードです。私の場合、他のJavaScriptを具体的に評価する必要はありませんでした。ページの読み込みが完了するまで待つ必要がありました。

var system = require('system');
if (system.args.length === 1) {
    console.log('Try to pass some arguments when invoking this script!');
}
else {
    var page = require('webpage').create();
    var address = system.args[1];

    page.open(address, function(status){
        page.onLoadFinished = function(status) {
            console.log(page.content);
            phantom.exit();
        };    
    });     
}

上記を「scrape.js」というファイルに保存し、次のように呼び出します。

phantomjs --ssl-protocol=any --ignore-ssl-errors=true scrape.js https://www.example.com

SSL関連のパラメーターは、特定のHTTPSサイトで発生していた他の問題(証明書の読み込みの問題に関連する)を回避するために追加されています。

これが誰かを助けることを願っています!

0
http203