ナックス「はい。というわけで、今日から遂に!画像収集シェルスクリプトを作成します!」
デビー君「いぇーい!」
ナックス「最初に、全体的なプログラムのイメージを解説します」
ナックス「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.シェルスクリプトに引数をプレゼント)」
クエリは、a=aaaの組み合わせが大事であって、http://●●.com?a=aaa&b=bbb&c=cccの?以降の順番は関係が無いのでした。
つまり、http://●●.com?b=bbb&c=ccc&a=aaaとしても、なんの問題もありません。余裕がある方は試してみてください。