「【Python 事始め】進捗を表示しながらダウンロードする」に続いて、Perl で同じことをやってみよう。Python の urllib モジュールに当たるのは、Perl では LWP::UserAgent モジュールだ1。
LWP::UserAgent – search.cpan.org
http://search.cpan.org/~gaas/libwww-perl-5.834/lib/LWP/UserAgent.pm
ファイルのダウンロードには get メソッドを使う。構文は次のようになっている。
$ua->get( $url, %options )
%options に指定できるオプションは非常に多岐にわたっていて複雑だが、とりあえずは 2 つだけ覚えておけばいい。
:content_file- 保存するファイル名
:content_cb- ブロックが読み出される度に呼び出される関数。引数としてブロックの中身と
HTTP::Responseオブジェクトが与えられる。
この 2 つのオプションはどちらか片方しか指定できない。つまり、進捗状況を表示するために :content_cb オプションを使うならば、ファイルの保存は自分でやらなければならないのだ。
スクリプトの例 download_test.pl
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use IO::File;
use URI;
# 標準出力をバッファリングしない
$|++;
# コマンドライン引数から URL を得る
my $url = URI->new( shift );
# URL からファイル名を得る
my $filename = ( split "/", $url->path )[ -1 ];
# ファイルを保存するためのファイルハンドル
my $fh = IO::File->new( $filename, "w" );
# 保存したバイト数
my $saved = 0;
# ダウンロード開始
LWP::UserAgent->new->get( $url, ":content_cb" => \&progress );
print "\n";
# ブロックが読み出される度に呼び出される関数
sub progress {
my ( $content, $response ) = @_;
# データの保存
$fh->print( $content );
$saved += length $content;
# 進捗の表示
my $total_size = $response->content_length;
my $percentage = $saved / $total_size * 100;
printf "%.2f %% ( %d KB )\r",
$percentage, $total_size / 1024;
}
実行例
$ perl download_test.pl "http://www.example.com/archive.zip" 12.34 % ( 567 KB )
- とはいえ、このモジュール自体はとてつもなく巨大で多機能だ。今回はそのうちファイルのダウンロード機能だけを使う。 ↩
