HTTPでのファイルダウンロードを並列に実行する


 HTTP::Asyncモジュールを使うとHTTPリクエストを並列に実行することができます。
 Parallel::ForkManagerモジュールを使うと処理を並列に実行することができるので、HTTPリクエスト処理を記述することでHTTPリクエストを並列に実行することができます。
use strict;
use warnings;
use HTTP::Async;
use HTTP::Request;
use URI;

my @uris = qw(
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g21-01.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g21-02.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g21-03.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g22-01.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g22-02.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g22-03.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g23-01.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g23-02.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g23-03.jpg
);

my $async = HTTP::Async->new(
    slots => 3, # 同時実行リクエスト数
);

foreach my $uri (@uris) {
    $async->add( HTTP::Request->new(GET => $uri) );
}

while (my $res = $async->wait_for_next_response) {
    print $res->request->uri, "\n";

    if ($res->is_success) {
        my $uri = URI->new($res->request->uri);
        my $path = $uri->path; # リクエストしたURIのパス
        my $file = (substr $path, -1) ne '/'
            ? (split /\//, $path)[-1]  # 最後の/以降の文字を取得
            : 'index.html'; # 最後が/の場合はindex.html
        
        open my $fh, ">", $file or warn "$!:$file";
        binmode $fh;
        print $fh $res->content;
        close $fh;
    } else {
        warn $res->status_line;
    }
}
use strict;
use warnings;
use Parallel::ForkManager;
use LWP::Simple;
use URI;

my @uris = qw(
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g21-01.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g21-02.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g21-03.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g22-01.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g22-02.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g22-03.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g23-01.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g23-02.jpg
    http://www2u.biglobe.ne.jp/~MAS/image/fractal/gallery21-25/g23-03.jpg
);

my $max_process = 3; # 同時実行リクエスト数
my $pm = Parallel::ForkManager->new($max_process);

foreach my $uri (@uris) {
    $pm->start and next;
    
    my $path = URI->new($uri)->path; # リクエストURIのパス
    my $file = (substr $path, -1) ne '/'
        ? (split /\//, $path)[-1]  # 最後の/以降の文字を取得
        : 'index.html'; # 最後が/の場合はindex.html
    mirror($uri, $file);
    print $uri, "\n";
    
    $pm->finish;
}
$pm->wait_all_children;

関連項目

Webページの取得