POEでRedTubeのビデオをダウンロードする
perlの勉強がてら。
Suger::Args使ってみた。
idが1〜10000のビデオを順に落とす。
(ほぼ全部落とす)
use strict; use warnings; use HTTP::Request::Common qw(GET); use POE qw(Component::Client::HTTP Sugar::Args); my @ids = 1..10000; my $save_dir = "/tmp/"; my @map = qw( R 1 5 3 4 2 O 7 K 9 H B C D X F G A I J 8 L M Z 6 P Q 0 S T U V W E Y N); sub get_url { my $id = shift; my $dir = sprintf("%07d" , int($id / 1000)); $id = sprintf("%07d", $id); my @id = split //, $id; my $my_int = 0; for my $i (0..6){ $my_int += $id[$i] * ($i+1) } my @my_int = split // , $my_int; my $val = 0; for (@my_int){ $val += $_; } $my_int = $val; $val = sprintf("%02d", $val); my @val = split //, $val; my $mapping .= $map[ord($id[3]) - 48 + $my_int + 3]; $mapping .= $val[1]; $mapping .= $map[ord($id[0]) - 48 + $my_int + 2]; $mapping .= $map[ord($id[2]) - 48 + $my_int + 1]; $mapping .= $map[ord($id[5]) - 48 + $my_int + 6]; $mapping .= $map[ord($id[1]) - 48 + $my_int + 5]; $mapping .= $val[0]; $mapping .= $map[ord($id[4]) - 48 + $my_int + 7]; $mapping .= $map[ord($id[6]) - 48 + $my_int + 4]; "http://dl.redtube.com/_videos_t4vn23s9jc5498tgj49icfj4678/$dir/$mapping.flv"; } POE::Component::Client::HTTP->spawn( Alias => 'ua', Streaming => 4096, ); sub got_response { my $id = shift; $id = sprintf("%07d", $id); return sub { my $poe = sweet_args; my $file = "$save_dir$id.flv"; my $response_packet = $poe->args->[1]; my ($response, $data) = @$response_packet; my $code = $response->code; if($code == 200){ unless ($poe->heap->{$file}){ print "write file = $file\n"; open my $FILE, ">>", $file or die; $poe->heap->{$file} = $FILE; } my $FILE = $poe->heap->{$file}; if (defined $data) { print $FILE $data; }else{ close $FILE; $id = shift @ids; create_session($id) if $id; } }elsif ($code == 403){ push @ids, $id; }else{ print "id = $id return_code = $code\n"; $id = shift @ids; create_session($id) if $id; } } } sub _start { my $id = shift; my $url = get_url($id); return sub{ my $poe = sweet_args; print "id = $id request $url\n"; $poe->kernel->post("ua" => "request", "got_response", GET $url); } } sub create_session { my $id = shift; my $f1 = _start($id); my $f2 = got_response($id); POE::Session->create( inline_states => { _start => \&$f1, got_response => \&$f2, }, ); } foreach (0..2){ my $id = shift @ids; create_session($id); } $poe_kernel->run();
Streamingモードのサンプルってあんまり見かけないということはダウンローダーとして使用してないんだね、みんな。
ホントはRangeとか投げてレジュームできるようにしないといかんのだろうけど
基本3多重で動くはずなんだけど。4とかになったり。むむうーってところがあったりかなり適当。
あとファイルの書き出しもWheelとか使わないとダメなのかな。
やっぱPOEを使ってみたけどやっぱわからない所多いな。
そもそもperlの知識がまだまだ。
うくく。