私のアプリケーションでは、LWPを使用して定期的にWebページを取得します。とにかくWebページが何らかの点で変更されている(明示的に比較している以外の)2つの連続したフェッチの間にあるかどうかをチェックするにはどうしますか?可能性のある変更を確認するために古いシグネチャと比較して抽出できる下位プロトコル層で生成されているシグネチャ(CRCなど)はありますか?変更されたウェブページを検出する方法は?
答えて
2つの方法が考えられます。 1つは、ページのダイジェストを使用することです。
use strict;
use warnings;
use Digest::MD5 'md5_hex';
use LWP::UserAgent;
# fetch the page, etc.
my $digest = md5_hex $response->decoded_content;
if ($digest ne $saved_digest) {
# the page has changed.
}
別のオプションは、サーバーが要求されたリソースのための1つを提供場合はHTTPのETag、を使用することです。単にそれを保存し、後で要求にIf-None-Match
フィールドを含めるようにリクエストヘッダーを設定するだけです。サーバーETagが同じままであれば、304 Not Modified
のステータスと空の応答本文が表示されます。それ以外の場合は、新しいページを取得します。 (そして新しいETag。)RFC2616のEntity Tagsを参照してください。
もちろん、コンテンツが変更されても、サーバーが横たえて同じETagを送信する可能性があります。あなたが見ない限り、知る方法はありません。
If-Modified-Since
request headerを使用する必要があります。これは、RFCに記載された問題点に留意してください。このヘッダーを要求とともに送信します。サーバーがそれをサポートしていて、コンテンツが新しいと判断した場合は、それをあなたに送信します。最新のバージョンを持っていると思われる場合は、メッセージ本文のない304
を返します。
しかし、他の回答が指摘しているように、サーバーはあなたに真実を伝える必要はないので、コンテンツをダウンロードして自分で確認することができないことがあります。多くの開発者がWebアプリで基本的なHTTPのサポートを考えていないため、多くの動的なものは常に新しいコンテンツを持つと主張します。 LWPビットの場合
、あなたは余分なヘッダを単一の要求を作成することができます。すべての要求については
use HTTP::Request;
use LWP::UserAgent;
my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->new(GET => $url);
$r->header('If-Modified-Since' => $time);
$ua->request($request);
、あなたは要求ハンドラを設定することができます
$ua->add_handler(
request_send => sub {
my($request, $ua, $h) = @_;
# ... look up time from local store
$r->header('If-Modified-Since' => $time);
}
);
をしかし、LWPを行うことができますあなたは、ファイルを保存したい場合はmirror
とあなたのためにこの最も:
$ua->mirror($url, $filename)
参照[HEAD](http://www.w3.org/Protocols/rfc261 6/rfc2616-sec9.html#sec9.4)リクエストを送信します。最後に変更されたコンテンツの長さなどを確認できます。 – Rob
特定のWebサイトに対する一般的な解決策または解決策が必要ですか。最高のソリューション(CPUとネットワークの使用効率がより高い)は、サーバーの機能に依存する可能性があるため、私は尋ねています。 – dolmen