2016-04-27 4 views
0

今私がやっているのは、間隔を設定して変更を探すことです。何か変更があった場合、私のスクリプトは私に警告し、そうでなければ1秒待ってから再度チェックします。これを行うより良い方法はありますか?私のスクリプトが探している情報は時間に敏感ですので、スクリプトが私に遅すぎると警告するなら、私はその情報で何もすることができません。だから私は何が起こっているとすぐに任意の変更を警告することができるより良いアプローチがあるのですか?時間の影響を受けやすい情報を探すための良い方法はありますか?

コード:あなたのケースのように、同期ループを使用している場合

page.open(url) 
timer = Date.now(); 
do{ 
if(Date.now()-timer>=1000){ 
//Look for change 
} 
timer =Date.now() 
}while (no chnages) 

答えて

0

PhantomJSはうまく動作しません。 JavaScriptはシングルスレッドなので、実行をブロックします。遅延

あなたは確かにこの場合のためにsetTimeoutsetIntervalを使用することができます。

var interval = 1000; // change according to needs 
page.open(url, function(){ 
    setTimeout(function retry(){ 
     var condition = page.evaluate(...); 
     if (!condition) { 
      setTimeout(retry, interval); 
     } else { 
      // TODO: what to do on success 
     } 
    }, interval); 
}); 

setInterval例も同様になります。実際、PhantomJSのexamplesフォルダにあるのはwaitFor()です。これらのアプローチの問題は、もちろん、変更とその変更の通知との間の遅延の可能性があります。もちろん、何も違いが見えなくなるまで、再試行間隔を減らすことはできます。

遅延なし

遅れなく変更を検出するには、少なくとも2つの方法があります。

page.onResourceReceived event
  • 登録すると、あなたが興味の変化は、(それはリクエストのボディに見てすることはできません)提供限られた情報で何が起こったかどうかを確認してみてください。

  • (接頭辞を持つ可能性が1.xで)PhantomJS 2.xでは、あなたは(page.evaluate()で)ページコンテキストにおけるDOMの変化を見てMutationObserverを作成することができ、その後、あなたがからの即時通知を送信ページコンテキスト(MutationObserverイベントハンドラから)をwindow.callPhantom and page.onCallback pairを使用して外部コンテキストに送信します。

1

あなたがフェッチしているリソースが正しく最終更新ヘッダを設定している場合は、それ最初のHTTP HEADリクエストを作成する方が効率的かもしれない、とだけそれが変更されている場合PhantomJSでページを開きます。これは間違いなくより複雑なので、最初に他のオプションを調べる価値があります。

http://stackoverflow.comの最終更新時刻を確認するサンプルコードは次のとおりです。

var url = 'http://stackoverflow.com'; 
var page = require('webpage').create(); 
var interval = 1000; // change according to needs 
var previousLastModified; 
(function modifiedCheck() { 
    var xhr = new XMLHttpRequest(); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4 && xhr.status == 200) { 
      var lastModified = xhr.getResponseHeader("Last-Modified"); 
      if (lastModified !== previousLastModified) { 
       page.open(url, function(status) { 
        if (status === 'success') { 
         previousLastModified = lastModified; 
         // TODO: do something with fetched page 
         console.log('fetched page.'); 
        } 
        setTimeout(modifiedCheck, interval); 
       }); 
      } else { 
       setTimeout(modifiedCheck, interval); 
      } 
     } 
    }; 
    console.log('making HEAD request.'); 
    xhr.open('HEAD', url); 
    xhr.send(); 
})(); 

コンソールログから、ページが1分間キャッシュされていることがわかります。

この例の自己実行modifiedCheck関数は、匿名関数を使用してAJAX呼び出しの結果とPhantomJSページのロードの両方を非同期に処理し、ブロックを制限します。

AJAX呼び出しをエラーなしで実行できるようにするには、--web-security=falseオプションを指定してPhantomJSを実行する必要があります。

関連する問題