「画像ダウンローダー」を作る際に
  気をつけたいいくつかのこと

     2012-09-28 LT-thon@YAPC::Asia2012

               発表者:@ turugina
What is 「画像ダウンローダー」
●   NOT 「画像検索システム等用のクローラー」
What is 「画像ダウンローダー」
●   BUT 個人で愉しむために画像をダウンロードする
    ツール
    –   ex) 某巨大掲示板の二次元画像板のスレから
code
●   画像ダウンロードツールを作る過程で色々な知
    識・技術が身に付く
    –   HTTP 関連 (LWP::UserAgent, HTTP::Lite,...)
    –   ファイル関連 (File::Spec, Path::Class, ...)
    –   コマンドラインオプション解析 (Getopt::*,...)
    –   永続化 / データベース (Tie::Persistent, Storable,
        DBI, DBD::SQLite, …)
    –   並行処理 / 排他制御 (threads, Coro, AnyEvent)
Agenda
●   ① 汝、紳士たれ
●   ② 画像だと思ったら HTML だった、しにたい
●   ③ \ Be on your guard! /
●   ④ 貪欲に、貪欲に
●   その他細々したもの
① 汝、紳士たれ
●   ダウンロード先のサイトに迷惑をかけない
    –   同じ URL から何度もダウンロードしない
        ●   → Tie::Persistent によるなんちゃって KVS でダウンロード
            済み URL を永続化
        ●   → でも量が増えてきたら素直に DBI/DBD::SQLite
    –   コネクションをキャッシュする
        ●   → $ua->conn_cache(
            LWP::ConnCache->new ( total_capacity => undef ) );
    –   できれば1サイト 1 コネクションで済ませる ( 古い? )
② 画像だと思ったら(以下略
●   ヘッダをチェックする
    –   my $res = $ua->mirror($url, $file);
        unlink($file) if $res->header('Content-Type') =~
        m/text/i;
●   たまに image/jpeg とか言いつつ HTML を返し
    てくる奴が ...
    –   → Imager に食わせてエラーになったら消すとか
③Be on your guard!
●   見たくない画像から身を守る
    –   サイトのブラックリスト( Og**sh とか Ro**en とか )
    –   もしダウンロードしてしまったら
        ●   →URL とファイルのハッシュ (md5/SHA1 等 ) をブラックリス
            トに登録して削除
             –   Digest::MD5 、 Digest::SHA1
    –   ダウンロード前に URL チェック、ダウンロード後にハッ
        シュチェックで 2 重のガード
④ 欲望に忠実に貪欲に、貪欲に
●   並行処理
    –   fork() ...?
    –   use threads; use Thread::Queue;
         ●   固定数のワーカスレッドを立てて Queue から URL を流し込
             む
    –   use POE; …?
    –   use Coro; use Coro::LWP;
    –   use AnyEvent; use AnyEvent::HTTP;
        use Coro; use Coro::AnyEvent;
細々
●   use Clipboard; で「画像 URL を含むテキストを
    コピー&ペースト」の「ペースト」の部分を自動化
●   コマンドラインオプションを付けたい→ Getopt::*
●   win32perl ではファイル操作時の文字コードに注
    意
    –   「 . ニーソ フォルダを作ってその中に画像をダウンロー
        ドしようとしたらカレントフォルダに変な名前のファイル
        が!!」
おまけ
●   use threads; 版と同じ処理内容のスクリプトを
    Python で書いてみたら
    –   コードは若干短く
    –   処理速度は若干速く
    –

    –

    –   なりました ...orz
        ●   くやしい!でも ..( ビクンビクン
ご清聴ありがとうございました

Yapcasia2012 ltthon

  • 1.
  • 2.
    What is 「画像ダウンローダー」 ● NOT 「画像検索システム等用のクローラー」
  • 3.
    What is 「画像ダウンローダー」 ● BUT 個人で愉しむために画像をダウンロードする ツール – ex) 某巨大掲示板の二次元画像板のスレから
  • 4.
  • 5.
    画像ダウンロードツールを作る過程で色々な知 識・技術が身に付く – HTTP 関連 (LWP::UserAgent, HTTP::Lite,...) – ファイル関連 (File::Spec, Path::Class, ...) – コマンドラインオプション解析 (Getopt::*,...) – 永続化 / データベース (Tie::Persistent, Storable, DBI, DBD::SQLite, …) – 並行処理 / 排他制御 (threads, Coro, AnyEvent)
  • 6.
    Agenda ● ① 汝、紳士たれ ● ② 画像だと思ったら HTML だった、しにたい ● ③ \ Be on your guard! / ● ④ 貪欲に、貪欲に ● その他細々したもの
  • 7.
    ① 汝、紳士たれ ● ダウンロード先のサイトに迷惑をかけない – 同じ URL から何度もダウンロードしない ● → Tie::Persistent によるなんちゃって KVS でダウンロード 済み URL を永続化 ● → でも量が増えてきたら素直に DBI/DBD::SQLite – コネクションをキャッシュする ● → $ua->conn_cache( LWP::ConnCache->new ( total_capacity => undef ) ); – できれば1サイト 1 コネクションで済ませる ( 古い? )
  • 8.
    ② 画像だと思ったら(以下略 ● ヘッダをチェックする – my $res = $ua->mirror($url, $file); unlink($file) if $res->header('Content-Type') =~ m/text/i; ● たまに image/jpeg とか言いつつ HTML を返し てくる奴が ... – → Imager に食わせてエラーになったら消すとか
  • 9.
    ③Be on yourguard! ● 見たくない画像から身を守る – サイトのブラックリスト( Og**sh とか Ro**en とか ) – もしダウンロードしてしまったら ● →URL とファイルのハッシュ (md5/SHA1 等 ) をブラックリス トに登録して削除 – Digest::MD5 、 Digest::SHA1 – ダウンロード前に URL チェック、ダウンロード後にハッ シュチェックで 2 重のガード
  • 10.
    ④ 欲望に忠実に貪欲に、貪欲に ● 並行処理 – fork() ...? – use threads; use Thread::Queue; ● 固定数のワーカスレッドを立てて Queue から URL を流し込 む – use POE; …? – use Coro; use Coro::LWP; – use AnyEvent; use AnyEvent::HTTP; use Coro; use Coro::AnyEvent;
  • 11.
    細々 ● use Clipboard; で「画像 URL を含むテキストを コピー&ペースト」の「ペースト」の部分を自動化 ● コマンドラインオプションを付けたい→ Getopt::* ● win32perl ではファイル操作時の文字コードに注 意 – 「 . ニーソ フォルダを作ってその中に画像をダウンロー ドしようとしたらカレントフォルダに変な名前のファイル が!!」
  • 12.
    おまけ ● use threads; 版と同じ処理内容のスクリプトを Python で書いてみたら – コードは若干短く – 処理速度は若干速く – – – なりました ...orz ● くやしい!でも ..( ビクンビクン
  • 13.