Linuxゲリラ戦記

画像収集スクリプトの作り方を解説しますので、友達収集スクリプトの作り方を教えてください。

46.画像収集プログラムの基本的な考え方を理解する。

ナックス「はい。というわけで、今日から遂に!画像収集シェルスクリプトを作成します!」

デビー君「いぇーい!」

ナックス「最初に、全体的なプログラムのイメージを解説します」

ナックス「1.まずは、curlコマンドでGoogle APIから画像情報を取得します」

ナックス「2.次に、その出力結果をパイプ(|←これね)でつなげて、trコマンドで整理します」

デビー君「ここまでは前回までの流れとほぼ同じだね」

ナックス「3.次に、さらに出力結果をパイプ(|←これね)でつなげて、grepコマンドで"url"と出力されている行だけ取り出します」

デビー君「おぉっ。なるほど。画像のアドレスだけを取り出すんだね」

ナックス「4.そして、そこからtrコマンドとは別の置換コマンドで、画像アドレス以外の情報を空文字に置換します」

デビー君「カラモジと置き換えるんだね?カラモジってなに?」

ナックス「空文字とは、何も書かれていない文字のことです」

デビー君「??」

ナックス「つまり、文字を削除するということです」

デビー君「あー。アドレス以外の"url"とかの文字を削除するんだね。ん?文字の削除ってわざわざ置換コマンドでやるの?削除用のコマンドは無いの?」

ナックス「はい。(多分)無いです。『置換コマンドで出来ちゃうんだから、削除用のコマンドってわざわざいらなくね?』みたいなノリだと思います。多分」

ナックス「で、その画像アドレスのみが書かれているものを、リダイレクトでバシッとファイルに書き込みます」

デビー君「ほうほう」

ナックス「5.でもって、次にwgetコマンドを使います。どうやらwgetのmanコマンドによると」

$ wget -i ファイル名

ナックス「で、ファイルに書かれているアドレスからファイルを一気に取得できるらしいです」

ナックス「以上です」

デビー君「おお……。なんだか、ナックスの解説無しでも、頑張れば作れそうな気がする」

ナックス「そうですね。もちろん、細かい部分ではwhile文で何回も処理を回して一度に大量の画像を取得するなどの作業も必要になりますが、こう見ると、結構簡単に作れそうな事が分かると思います」

ナックス「さて。まぁ作成途中なので、厳格には検索キーワードを決めなくても良いのですが(どうせ、作成後にも好きなのに変えられるし)、とりあえずの検索キーワードを決めないといけませんね」

デビー君「そうだね」

ナックス「で、まぁトイレの神様との約束(36.ファイルを検索する、findコマンド、locateコマンド。何のファイルか調べる、fileコマンド。参照)もあることですし、今回は単純に『壁紙』という検索キーワードで作成していきたいと思います」

デビー君「はーい」

ナックス「というわけで、まずは『壁紙』という検索キーワードをURLエンコードしなければなりません」

デビー君「ゆーあーるえるえんこーど……?」

ナックス「などとデビー君の様に忘れている方は、40.Linuxのコマンドから行うURLエンコード、URLデコードをチェックしてみてください」

ナックス「今回は壁紙というキーワードをURLエンコードしたいので、以下の様にコマンドを打てば良いことになります」

$ echo 壁紙 | nkf -wMQ | tr = %

ナックス「結果はこんな感じです」

$ echo 壁紙 | nkf -wMQ | tr = %
%E5%A3%81%E7%B4%99

ナックス「このURLエンコードされた文字を使いつつgoogleAPIへ投げるクエリを作成していきます」

ナックス「Google画像検索APIのベースとなるアドレスは以下の物でした」

http://ajax.googleapis.com/ajax/services/search/images

ナックス「まずは、これに検索キーワードのクエリをくっつけましょう。今回は壁紙、という検索キーワードです。URLエンコードされた文字を使わなければなりません。検索キーワードは」

q=[(URLエンコードされた)検索キーワード]

ナックス「というような形式でした。つまり、以下の様になります」

http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99

ナックス「もう一つ、必ずつけなければならないクエリとして、バージョン番号がありました」

v=[バージョン番号]

ナックス「バージョン番号は、現在は1.0しかないので、1.0と指定します」

http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0

ナックス「ここまでが必ず指定しなければならない基本のクエリでしたね」

ナックス「今回はさらに詳しくクエリを指定していきたいと思います」

ナックス「まず、どの国のGoogle画像検索を使用するか、を指定します」

hl=[国コード]

ナックス「エイチ・(大文字の)アイではなく、エイチ・(小文字の)エルであることに気をつけてください。APIによって、国コードに多少の違いがあります。例えば、日本の場合はjpと指定する場合とjaと指定する場合があります。APIの説明ページ(クラス リファレンス - Google AJAX Search API - Google Code)には残念ながら、どの国にどのような国コードを指定すれば良いかの例が載っていませんでしたが、実際に日本のGoogle画像検索で検索結果のアドレスを確認して見たところ、日本はjaと指定するようです」

http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja

ナックス「一般的には、ネットワークの世界ではブラウザなどのソフトは勝手に『基本的に日本語の情報を見せてね』などとサーバーに指定します。恐らく私たちもhlを省略して良い気もします……が、curlコマンドが実際に『日本語でよろしくー』と言ってくれてるかどうかはわからないので、ここできっちりと指定しておきましょう」

ナックス「次に、一度に返ってくる検索結果の数を指定します」

rsz=small(4件の結果が返ってくる)
rsz=large(8件の結果が返ってくる)

ナックス「今回は8件の結果が返ってくるよう指定します」

http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large

ナックス「さらに今回は、検索結果のページ番号を指定します」

ナックス「正確には、APIから返ってくる結果なので『ページ』と言う概念は無いです。APIの解説ページでは『開始インデックス(開始先頭位置)』という言葉を使っていますね」

start=開始インデックス

ナックス「とりあえず、先頭の0を指定しておきましょう」

http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0

ナックス「さらに、セーフモードを最初からオフにしておきましょう」

safe=active(セーフサーチフィルタリング強)
safe=moderate(セーフサーチフィルタリング中)
safe=off(セーフサーチフィルタリング無効)
http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off

ナックス「今回はとりあえずこんな感じな指定でいきたいと思います。もちろん、他にもクエリで指定できますので、クラス リファレンス - Google AJAX Search API - Google Code 画像検索固有の引数を確認してみてください」

ナックス「さて。アドレスさえ作成出来ればこちらのものです。とりあえずcurlコマンドを使用して、エラーコードが返ってこないか確認してみますか」

$ curl -e http://www.my-ajax-site.com \
        'http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off'

ナックス「実効結果はこんな感じです」

$ curl -e http://www.my-ajax-site.com \
>         'http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off'
{"responseData": {"results":[{"GsearchResultClass":"GimageSearch","width":"1600","height":"1200","imageId":"Kk9PQPUbc5LihM:","tbWidth":"150","tbHeight":"113","unescapedUrl":"http://gigazine.jp/img/2008/01/30/vladstudio/vladstudio000.jpg","url":"http://gigazine.jp/img/2008/01/30/vladstudio/vladstudio000.jpg","visibleUrl":"gigazine.net","title":"プロが作った高いクオリティの\u003cb\u003e壁紙\u003c/b\u003eがダウンロード可能なサイト \u003cb\u003e...\u003c/b\u003e","titleNoFormatting":"プロが作った高いクオリティの壁紙がダウンロード可能なサイト ...","originalContextUrl":"http://gigazine.net/index.php?/news/comments/20080130_vladstudio/","content":"KDE4.0のデフォルト\u003cb\u003e壁紙\u003c/b\u003e","contentNoFormatting":"KDE4.0のデフォルト壁紙","tbUrl":"http://images.google.com/images?q\u003dtbn:Kk9PQPUbc5LihM::gigazine.jp/img/2008/01/30/vladstudio/vladstudio000.jpg"},{"GsearchResultClass":"GimageSearch","width":"1600","height":"1200","imageId":"y9FTzUpodsulvM:","tbWidth":"150","tbHeight":"113","unescapedUrl":"http://holyday.jp/dive/wp001_skyblue.jpg","url":"http://holyday.jp/dive/wp001_skyblue.jpg","visibleUrl":"ameblo.jp","title":"ホーリーのダイビング&シュノーケリング旅行記(旅記・水中写真・期間 \u003cb\u003e...\u003c/b\u003e","titleNoFormatting":"ホーリーのダイビング&シュノーケリング旅行記(旅記・水中写真・期間 ...","originalContextUrl":"http://ameblo.jp/holydive/","content":"日替わり\u003cb\u003e壁紙\u003c/b\u003eシリーズで、空の","contentNoFormatting":"日替わり壁紙シリーズで、空の","tbUrl":"http://images.google.com/images?q\u003dtbn:y9FTzUpodsulvM::holyday.jp/dive/wp001_skyblue.jpg"},{"GsearchResultClass":"GimageSearch","width":"400","height":"310","imageId":"4B2rNXAM9xTNMM:","tbWidth":"124","tbHeight":"96","unescapedUrl":"http://gigazine.jp/img/2007/02/25/wallpaper/000_m.jpg","url":"http://gigazine.jp/img/2007/02/25/wallpaper/000_m.jpg","visibleUrl":"gigazine.net","title":"ステキなデスクトップ用\u003cb\u003e壁紙\u003c/b\u003e配布サイトまとめ - GIGAZINE","titleNoFormatting":"ステキなデスクトップ用壁紙配布サイトまとめ - GIGAZINE","originalContextUrl":"http://gigazine.net/index.php?/news/comments/20070225_wallpaper/","content":"ステキなデスクトップ用\u003cb\u003e壁紙\u003c/b\u003e配布","contentNoFormatting":"ステキなデスクトップ用壁紙配布","tbUrl":"http://images.google.com/images?q\u003dtbn:4B2rNXAM9xTNMM::gigazine.jp/img/2007/02/25/wallpaper/000_m.jpg"},{"GsearchResultClass":"GimageSearch","width":"1024","height":"768","imageId":"naTwEVQaQLp4FM:","tbWidth":"150","tbHeight":"113","unescapedUrl":"http://www.beroncho.com/wallpaper/1150820534183/image/1150820534183.jpg","url":"http://www.beroncho.com/wallpaper/1150820534183/image/1150820534183.jpg","visibleUrl":"www.beroncho.com","title":"イラスト\u003cb\u003e壁紙\u003c/b\u003e@\u003cb\u003e壁紙\u003c/b\u003e(一般)","titleNoFormatting":"イラスト壁紙@壁紙(一般)","originalContextUrl":"http://www.beroncho.com/wallpaper/1150820534183/","content":"イラスト\u003cb\u003e壁紙\u003c/b\u003e","contentNoFormatting":"イラスト壁紙","tbUrl":"http://images.google.com/images?q\u003dtbn:naTwEVQaQLp4FM::www.beroncho.com/wallpaper/1150820534183/image/1150820534183.jpg"},{"GsearchResultClass":"GimageSearch","width":"1280","height":"1024","imageId":"9c7S39UzQZeytM:","tbWidth":"150","tbHeight":"120","unescapedUrl":"http://img01.ti-da.net/usr/kisecc/kisecc_paper02.jpg","url":"http://img01.ti-da.net/usr/kisecc/kisecc_paper02.jpg","visibleUrl":"kisecc.ti-da.net","title":"日本プロゴルフ選手権インフォメーションセンター|喜瀬カントリー \u003cb\u003e...\u003c/b\u003e","titleNoFormatting":"日本プロゴルフ選手権インフォメーションセンター|喜瀬カントリー ...","originalContextUrl":"http://kisecc.ti-da.net/c50395.html","content":"画像をクリックすると\u003cb\u003e壁紙\u003c/b\u003e用画像","contentNoFormatting":"画像をクリックすると壁紙用画像","tbUrl":"http://images.google.com/images?q\u003dtbn:9c7S39UzQZeytM::img01.ti-da.net/usr/kisecc/kisecc_paper02.jpg"},{"GsearchResultClass":"GimageSearch","width":"1280","height":"1024","imageId":"Ejpz50CEEhMySM:","tbWidth":"150","tbHeight":"120","unescapedUrl":"http://www.anisen.tv/usr/animekabegami/%E3%83%8F%E3%83%AB%E3%83%92%E5%A3%81%E7%B4%99_%E6%9C%80%E7%B5%82.png","url":"http://www.anisen.tv/usr/animekabegami/%25E3%2583%258F%25E3%2583%25AB%25E3%2583%2592%25E5%25A3%2581%25E7%25B4%2599_%25E6%259C%2580%25E7%25B5%2582.png","visibleUrl":"animekabegami.anisen.tv","title":"アニメ好きの皇帝による\u003cb\u003e壁紙\u003c/b\u003e配布","titleNoFormatting":"アニメ好きの皇帝による壁紙配布","originalContextUrl":"http://animekabegami.anisen.tv/c4852.html","content":"季節感完全無視の\u003cb\u003e壁紙\u003c/b\u003eを貼って","contentNoFormatting":"季節感完全無視の壁紙を貼って","tbUrl":"http://images.google.com/images?q\u003dtbn:Ejpz50CEEhMySM::www.anisen.tv/usr/animekabegami/%25E3%2583%258F%25E3%2583%25AB%25E3%2583%2592%25E5%25A3%2581%25E7%25B4%2599_%25E6%259C%2580%25E7%25B5%2582.png"},{"GsearchResultClass":"GimageSearch","width":"1000","height":"728","imageId":"S5jSViPAi4AwjM:","tbWidth":"149","tbHeight":"108","unescapedUrl":"http://blog-imgs-31-origin.fc2.com/n/a/k/nakasoku/vip1004141.jpg","url":"http://blog-imgs-31-origin.fc2.com/n/a/k/nakasoku/vip1004141.jpg","visibleUrl":"nakasoku.blog18.fc2.com","title":"かっこいいデスクトップの\u003cb\u003e壁紙\u003c/b\u003eくれ | 中の人","titleNoFormatting":"かっこいいデスクトップの壁紙くれ | 中の人","originalContextUrl":"http://nakasoku.blog18.fc2.com/blog-entry-558.html","content":"かっこいいデスクトップの\u003cb\u003e壁紙\u003c/b\u003e","contentNoFormatting":"かっこいいデスクトップの壁紙","tbUrl":"http://images.google.com/images?q\u003dtbn:S5jSViPAi4AwjM::blog-imgs-31-origin.fc2.com/n/a/k/nakasoku/vip1004141.jpg"},{"GsearchResultClass":"GimageSearch","width":"560","height":"329","imageId":"LJ6-M4XxryC5fM:","tbWidth":"133","tbHeight":"78","unescapedUrl":"http://blog.creamu.com/mt/img/wallpapersverhau.jpg","url":"http://blog.creamu.com/mt/img/wallpapersverhau.jpg","visibleUrl":"blog.creamu.com","title":"大自然のクールな\u003cb\u003e壁紙\u003c/b\u003e集『wallpapers.verhau』 | CREAMU","titleNoFormatting":"大自然のクールな壁紙集『wallpapers.verhau』 | CREAMU","originalContextUrl":"http://blog.creamu.com/mt/2008/01/wallpapersverhau.html","content":"かっこいい\u003cb\u003e壁紙\u003c/b\u003eを探している。","contentNoFormatting":"かっこいい壁紙を探している。","tbUrl":"http://images.google.com/images?q\u003dtbn:LJ6-M4XxryC5fM::blog.creamu.com/mt/img/wallpapersverhau.jpg"}],"cursor":{"pages":[{"start":"0","label":1},{"start":"8","label":2},{"start":"16","label":3},{"start":"24","label":4},{"start":"32","label":5},{"start":"40","label":6},{"start":"48","label":7},{"start":"56","label":8}],"estimatedResultCount":"923000","currentPageIndex":0,"moreResultsUrl":"http://www.google.com/images?oe\u003dutf8\u0026ie\u003dutf8\u0026source\u003duds\u0026start\u003d0\u0026safe\u003doff\u0026hl\u003den\u0026q\u003d%E5%A3%81%E7%B4%99"}}, "responseDetails": null, "responseStatus": 200}

デビー君「一番最後の"responseStatus"が200だったら、特にエラーが無い正常な状態、という意味だったね」

ナックス「ここまで来たら、一番最初に言った手順の1〜3まで一気にやってしまいますか」

デビー君「えーっと、パイプで」

tr , \\n

デビー君「をくっつけて、さらにパイプでgrepを」

grep "url"

デビー君「みたいにくっつけるのかな?」

ナックス「その通りです」

デビー君「なるほど。つまり、こういうことだね?」

$ curl -e http://www.my-ajax-site.com \
        'http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off' \
| tr , \\n | grep "url"

ナックス「そうです。実行結果は以下の様になります」

$ curl -e http://www.my-ajax-site.com \
>         'http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off' \
> | tr , \\n | grep "url"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7512    0  7512    0     0   4737      0 --:--:--  0:00:01 --:--:-- 14473
"url":"http://gigazine.jp/img/2008/01/30/vladstudio/vladstudio000.jpg"
"url":"http://holyday.jp/dive/wp001_skyblue.jpg"
"url":"http://gigazine.jp/img/2007/02/25/wallpaper/000_m.jpg"
"url":"http://www.beroncho.com/wallpaper/1150820534183/image/1150820534183.jpg"
"url":"http://img01.ti-da.net/usr/kisecc/kisecc_paper02.jpg"
"url":"http://www.anisen.tv/usr/animekabegami/%25E3%2583%258F%25E3%2583%25AB%25E3%2583%2592%25E5%25A3%2581%25E7%25B4%2599_%25E6%259C%2580%25E7%25B5%2582.png"
"url":"http://blog-imgs-31-origin.fc2.com/n/a/k/nakasoku/vip1004141.jpg"
"url":"http://blog.creamu.com/mt/img/wallpapersverhau.jpg"

ナックス「クエリで8件の結果が返ってくるように指定しましたが、きちんと8件の結果が返ってきている様ですね」

ナックス「というわけで、本日ご紹介の新しい置換コマンドの登場です」

ナックス「奴の名前はsedコマンド。使い方はオプション含めて色々あるけど、今回はもっともメジャーな文字の置換のやりかた」

sed -e 's/置換前の文字/置換後の文字/g'

ナックス「本当はsedコマンドは奥が深いので、出来れば他のサイトなども参考にしてね」

デビー君「今回はどういう風に使うの?」

ナックス「えーっと、[置換後の文字]に何も指定しなければ、その文字は削除されます」

デビー君「へー。えーっと、今回は"url":を削除したいんだから、上記のコマンドにさらにパイプで」

sed -e 's/"url"://g'

デビー君「とすれば良いのかな?」

ナックス「そうですね。でもそうすると」

"http://gigazine.jp/img/2008/01/30/vladstudio/vladstudio000.jpg"
"http://holyday.jp/dive/wp001_skyblue.jpg"
"http://gigazine.jp/img/2007/02/25/wallpaper/000_m.jpg"
"http://www.beroncho.com/wallpaper/1150820534183/image/1150820534183.jpg"
"http://img01.ti-da.net/usr/kisecc/kisecc_paper02.jpg"
"http://www.anisen.tv/usr/animekabegami/%25E3%2583%258F%25E3%2583%25AB%25E3%2583%2592%25E5%25A3%2581%25E7%25B4%2599_%25E6%259C%2580%25E7%25B5%2582.png"
"http://blog-imgs-31-origin.fc2.com/n/a/k/nakasoku/vip1004141.jpg"
"http://blog.creamu.com/mt/img/wallpapersverhau.jpg"

ナックス「となって、アドレス前後の"が取れません」

デビー君「あ、そうか。じゃあ、さらにパイプでつなげて」

sed -e 's/"//g'

デビー君「としようか……」

ナックス「いえ。sedコマンドでは、一度に複数の置換が可能な様です。つまり、今回は以下の様になります」

sed -e 's/"url"://g' -e 's/"//g'

デビー君「なるほど。じゃあ、これを合わせて考えると」

$ curl -e http://www.my-ajax-site.com \
        'http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off' \
| tr , \\n | grep "url" | sed -e 's/"url"://g' -e 's/"//g'

デビー君「っていうコマンドになるね」

ナックス「はい。結果はこうなります」

$ curl -e http://www.my-ajax-site.com \
>         'http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off' \
> | tr , \\n | grep "url" | sed -e 's/"url"://g' -e 's/"//g'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7512    0  7512    0     0  35194      0 --:--:-- --:--:-- --:--:--  171k
http://gigazine.jp/img/2008/01/30/vladstudio/vladstudio000.jpg
http://holyday.jp/dive/wp001_skyblue.jpg
http://gigazine.jp/img/2007/02/25/wallpaper/000_m.jpg
http://www.beroncho.com/wallpaper/1150820534183/image/1150820534183.jpg
http://img01.ti-da.net/usr/kisecc/kisecc_paper02.jpg
http://www.anisen.tv/usr/animekabegami/%25E3%2583%258F%25E3%2583%25AB%25E3%2583%2592%25E5%25A3%2581%25E7%25B4%2599_%25E6%259C%2580%25E7%25B5%2582.png
http://blog-imgs-31-origin.fc2.com/n/a/k/nakasoku/vip1004141.jpg
http://blog.creamu.com/mt/img/wallpapersverhau.jpg

デビー君「おー。綺麗にアドレスだけ抽出できたね」

ナックス「そうですね。せっかくですから、リダイレクトで適当な名前のテキストファイルに保存して、試しにwgetコマンドを使ってみますか」

デビー君「そうだね。えーっと、じゃあ、さっきのコマンドの最後に」

 > ahaha.txt

デビー君「とつければいいね」

ナックス「確かに適当とは言いましたけど、本当にテキトーなファイル名ですね……。これをご覧の皆さんは、特に上記のファイル名で無くて別の好きな名前のファイル名でも構いません」

$ curl -e http://www.my-ajax-site.com \
        'http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off' \
| tr , \\n | grep "url" | sed -e 's/"url"://g' -e 's/"//g' > ahaha.txt

デビー君「実行結果はこんな感じになったよ」

$ curl -e http://www.my-ajax-site.com \
>         'http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off' \
> | tr , \\n | grep "url" | sed -e 's/"url"://g' -e 's/"//g' > ahaha.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7512    0  7512    0     0  34691      0 --:--:-- --:--:-- --:--:--  100k

ナックス「どうやら ahaha.txt にアドレスが書き込まれた様ですね。それでは、iオプションをつけたwgetコマンドを使ってみましょう。うまくいけば、画像ファイルがダウンロードできるはずです」

$ wget -i ahaha.txt

ナックス「試した所、実行結果は以下の様になりました」

$ wget -i ahaha.txt 
--2010-08-28 18:30:59--  http://gigazine.jp/img/2008/01/30/vladstudio/vladstudio000.jpg
gigazine.jp をDNSに問いあわせています... 58.188.103.33, 219.75.253.85, 219.75.253.84, ...
gigazine.jp|58.188.103.33|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 507256 (495K) [image/jpeg]
`vladstudio000.jpg' に保存中

100%[=================================================================================================>] 507,256     1.02M/s 時間 0.5s    

2010-08-28 18:31:00 (1.02 MB/s) - `vladstudio000.jpg' へ保存完了 [507256/507256]

--2010-08-28 18:31:00--  http://holyday.jp/dive/wp001_skyblue.jpg
holyday.jp をDNSに問いあわせています... 210.172.144.10
holyday.jp|210.172.144.10|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 633949 (619K) [image/jpeg]
`wp001_skyblue.jpg' に保存中

100%[=================================================================================================>] 633,949     --.-K/s 時間 0.1s    

2010-08-28 18:31:00 (5.75 MB/s) - `wp001_skyblue.jpg' へ保存完了 [633949/633949]

--2010-08-28 18:31:00--  http://gigazine.jp/img/2007/02/25/wallpaper/000_m.jpg
gigazine.jp|58.188.103.33|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 49519 (48K) [image/jpeg]
`000_m.jpg' に保存中

100%[=================================================================================================>] 49,519      --.-K/s 時間 0.04s   

2010-08-28 18:31:00 (1.06 MB/s) - `000_m.jpg' へ保存完了 [49519/49519]

--2010-08-28 18:31:00--  http://www.beroncho.com/wallpaper/1150820534183/image/1150820534183.jpg
www.beroncho.com をDNSに問いあわせています... 219.94.128.167
www.beroncho.com|219.94.128.167|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 191489 (187K) [image/jpeg]
`1150820534183.jpg' に保存中

100%[=================================================================================================>] 191,489     --.-K/s 時間 0.1s    

2010-08-28 18:31:00 (1.40 MB/s) - `1150820534183.jpg' へ保存完了 [191489/191489]

--2010-08-28 18:31:00--  http://img01.ti-da.net/usr/kisecc/kisecc_paper02.jpg
img01.ti-da.net をDNSに問いあわせています... 202.152.209.41
img01.ti-da.net|202.152.209.41|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 295469 (289K) [image/jpeg]
`kisecc_paper02.jpg' に保存中

100%[=================================================================================================>] 295,469     --.-K/s 時間 0.08s   

2010-08-28 18:31:00 (3.64 MB/s) - `kisecc_paper02.jpg' へ保存完了 [295469/295469]

--2010-08-28 18:31:00--  http://www.anisen.tv/usr/animekabegami/%25E3%2583%258F%25E3%2583%25AB%25E3%2583%2592%25E5%25A3%2581%25E7%25B4%2599_%25E6%259C%2580%25E7%25B5%2582.png
www.anisen.tv をDNSに問いあわせています... 202.152.209.34
www.anisen.tv|202.152.209.34|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 404 Not Found
2010-08-28 18:31:00 エラー 404: Not Found。

--2010-08-28 18:31:00--  http://blog-imgs-31-origin.fc2.com/n/a/k/nakasoku/vip1004141.jpg
blog-imgs-31-origin.fc2.com をDNSに問いあわせています... 208.71.107.47
blog-imgs-31-origin.fc2.com|208.71.107.47|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 315223 (308K) [image/jpeg]
`vip1004141.jpg' に保存中

100%[=================================================================================================>] 315,223      287K/s 時間 1.1s    

2010-08-28 18:31:02 (287 KB/s) - `vip1004141.jpg' へ保存完了 [315223/315223]

--2010-08-28 18:31:02--  http://blog.creamu.com/mt/img/wallpapersverhau.jpg
blog.creamu.com をDNSに問いあわせています... 202.172.26.11
blog.creamu.com|202.172.26.11|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 26504 (26K) [image/jpeg]
`wallpapersverhau.jpg' に保存中

100%[=================================================================================================>] 26,504      93.7K/s 時間 0.3s    

2010-08-28 18:31:02 (93.7 KB/s) - `wallpapersverhau.jpg' へ保存完了 [26504/26504]

終了しました --2010-08-28 18:31:02--
ダウンロード完了: 7 ファイル、1.9M バイトを 2.2s で取得 (905 KB/s)
$

ナックス「残念ながら、一つは404 Not Foundエラーで取得できませんでしたが、残り7つの画像は取得出来ました」

画像の取得に成功

デビー君「404 Not Foundエラーって何?」

ナックス「『ネット上のそのアドレスにファイル等はありませんでした』という意味のエラーです。そのサイトの持ち主が、画像を削除したか、もしくはサイトの別の場所に移してしまったのかもしれません。まぁ、これは仕方の無いエラーですね」

デビー君「えーっと、もしかして、画像自動取得スクリプトはできちゃった感じ?」

ナックス「いえいえ。今回は基本的な考え方の解説です。目標は、一つのシェルスクリプトを実行するだけで、自動的に100以上の画像をダウンロードすることです」

ナックス「次回以降、今回の考え方を元にシェルスクリプトを作成していきます(47.シェルスクリプトに引数をプレゼント)」

補足

Google APIが使用できなくなっているのですが?

そうですね。そこで、代わりのアドレスを用意しました。解説で

http://ajax.googleapis.com/ajax/services/search/images?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off

としていますが、上記アドレスの代わりに

http://www.garunimo.com/program/linux/search/images.php?q=%E5%A3%81%E7%B4%99&v=1.0&hl=ja&rsz=large&start=0&safe=off

を使用してください。このアドレスは、実際の検索機能はありませんが、「rsz=largeが正しく指定されていれば、結果を8個返す。正しく指定されていない場合は4個返す」「実際にダウンロードできる画像のアドレスを返す」の2つの機能を備えています。ちなみに、実際にダウンロードできる画像に関してですが、あの有名なかわいいフリー素材集 いらすとやの画像を使用しています。

参考サイト
フィルタを使用した文字列操作 1 - UNIX & Linux コマンド・シェルスクリプト リファレンス
sed コマンドに関して参考にさせていただきました。
クエリの順序について

クエリは、a=aaaの組み合わせが大事であって、http://●●.com?a=aaa&b=bbb&c=cccの?以降の順番は関係が無いのでした。

つまり、http://●●.com?b=bbb&c=ccc&a=aaaとしても、なんの問題もありません。余裕がある方は試してみてください。

grepコマンドってなんでしたっけ?
grepで指定した文字があれば、その行だけを出力するコマンドです。14.パイプとgrep、less。を参照してください。
このエントリーをはてなブックマークに追加