街中で見かけて「グッときた人」の思い出

例えば、下記のようなスクリプトの場合、一度画像が保存された後、ファイルサイズをを抜き出すようになります。
ダウンロード前に、ファイルサイズをあらかじめ知りたいのですがどのようにしたら良いでしょうか?


use strict;
my $url = "http://img.www.goo.ne.jp/img/gh_logo.png";

use LWP::UserAgent;
use HTTP::Cookies;
use HTTP::Request;
use HTTP::Headers;

my $req = HTTP::Request->new(GET => $url);
my $ua = LWP::UserAgent->new;
$ua->agent( 'Mozilla/5.0 (Windows NT 6.0; rv:12.0)' );
$ua->timeout('10');
$ua->max_redirect();
$ua->cookie_jar( HTTP::Cookies->new(
file => '',
autosave => 1,
));

my $res = $ua->request($req, "save.png");
my $file_size = $res->header("content-length");
print $file_size;

A 回答 (3件)

質問の意図を取り違えていたかもしれません。



ダウンロードを開始する前にファイルサイズを知りたいのではなくて、
ダウンロードが完了する前にファイルサイズが知りたいということですね。

以下の例が参考になると思います。

404 Blog Not Found:perl - LWP::UserAgentで進捗表示しつつダウンロード
http://blog.livedoor.jp/dankogai/archives/511416 …

上の例では省略されていますが、:read_size_hintでコールバックを呼ぶサイズを指定できます。
    • good
    • 0
この回答へのお礼

まさに、求めていた情報です!ありがとうございます。

ただ、正直、使い方がいまいちよく分かりません。
':content_cb'のように、’’で囲むような表記は始めてみました。

また、色々調べて見たところ、下記のようにすると動くと思ったのですが、コールバックのサイズが変わってないようでした。

また、もし、元シンプルに、Content-Lengthのみ求めて、あとは通常の制御に戻る方法があれば教えていただければ幸いです。

my $res = LWP::UserAgent->new->get(
$uri,
':content_cb' => sub {
my ( $chunk, $res, $proto ) = @_;
print $wfh $chunk;
my $size = tell $wfh;
if (my $total = $res->header('Content-Length')){
printf "%d/%d (%f%%)\r", $size, $total, $size/$total*100;
}else{
printf "%d/Unknown bytes\r", $size;
}
},
':read_size_hint' => 100000000000000000000000000000000000,
);

お礼日時:2013/08/15 21:57

やりたいことは


[1] HTTPヘッダだけ要求し、接続を維持する
[2] 何かする
[3] 本体を要求する
ということでしょうか?

この接続というのがTCP/IPのことなら、TCP/IPの接続(socket接続)から実装すればできます
(1) クライアントがWebサーバへTCP/IPで接続する
(2) クライアントがHTTP Head でヘッダを要求する
(3) Webサーバがヘッダの応答をする
(4) クライアントがHTTP Get or Postで全体を取得する
(5) クラアイントがTCP/IPを切断する

WebでのTCP/IPは通常クライアントから切断します。これにより、TCP/IP接続を維持したまま、
連続でHTTPリクエストを投げることができます。ただし、Webサーバ側の設定でTCP/IPの
接続維持時間を短かく設定できるので、かならずしも(1)~(5)のようにできるとは限りません。

> ブラウザがやっているように、接続状態を維持したまま、すぐにダウンロードに移りたい
といっているのはTCP/IPの接続のことですよね?HTTP自体はコネクションレスなので、
リクエスト->レスポンスで終りです。
    • good
    • 0

use strict;


use warnings;
use feature 'say';
use LWP;
use HTTP::Request;

my $url = shift // die "usage : $0 url";
my $ua = LWP::UserAgent->new;
$ua->agent('Mozilla/5.0');
$ua->timeout(10);

my $req = HTTP::Request->new( HEAD => $url );
my $res = $ua->request($req);
$res->is_success or die $url, ': ', $res->message;

say '--- HTTP Header';
say $res->header('Content-Type');
say $res->header('Content-Length');
say $res->status_line;
say $res->code;
    • good
    • 0
この回答へのお礼

回答いただきありがとうございます。
確かに、これですと、ヘッダー情報が取得できるのですが、できれば、保存するために再度リクエストを飛ばすことなく、ブラウザがやっているように、接続状態を維持したまま、すぐにダウンロードに移りたいのですが、どのようにすればよいでしょうかね?

お礼日時:2013/08/14 23:51

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!