今日から12月ということでアドベントカレンダー初日。
Linuxゲリラ戦記の#38〜#46あたりの「APIを使って任意の画像を取得する」をやってみた。
Linuxゲリラ戦記ではGoogleのAPIを使っているがすでに終了したらしいのでかわりにFlickerAPIを使う。今回は大好きなパクチー料理の画像を取得して、一人でニヤニヤしようと思う*1
最終的に完成したコード
#!/bin/sh
# "パクチー料理"をエンコードし、APIを使ってデータを取得
curl "https://api.flickr.com/services/rest/?\
method=flickr.photos.search&api_key={APIキー}&format=rest&per_page=20\
&text=%E3%83%91%E3%82%AF%E3%83%81%E3%83%BC%E6%96%99%E7%90%86&extras=url_q" > temp.txt
# url-q の行だけを抜き出す
cat temp.txt | tr ' ' '\n' | tr -d '"' | grep "url_q" > url.txt
# 「url-q=」を削除
cat url.txt | sed s/url_q=/''/ > result.txt
# 画像を取得
wget -i result.txt -P image
解説
FlickerAPIのキーを取得
Flickr APIを使って画像ファイルをダウンロードするの「API Keyを取得する」の手順に沿って非商用のキーを取得する。
APIキーはFlickr Servicesから取得できる。
"パクチー料理"の文字列をエンコード
nkfコマンドを使って文字列を変換しUTF-8で出力する。その後「=」を「%」に変換しエンコード完成。
$ echo パクチー料理 |nkf -wMQ|tr = % %E3%83%91%E3%82%AF%E3%83%81%E3%83%BC%E6%96%99%E7%90%86
APIを使ってデータを取得
curlをつかってAPIを叩く。api_keyには取得したAPIキーを指定。
curl "https://api.flickr.com/services/rest/?\
method=flickr.photos.search&api_key={APIキー}
これだけでは任意の画像を指定して取得できないのでクエリを使って条件を追加する。クエリの接続には&をつかう。
per_page=20 画像を20件取得
text=%E3%83%91%E3%82%AF%E3%83%81%E3%83%BC%E6%96%99%E7%90%86 キーワードに「パクチー料理」を指定
extras=url_q" urlを取得*2
取得結果を「temp.txt」に一旦出力。
>temp.txt
実行結果

「url-q」を含む行だけを残す
trコマンドで、半角スペースを改行に置換し、取得データしたを改行する。
tr ' ' '\n'
実行結果に対して、さらにtrコマンドで、「"」を削除する。tr -dで指定した文字を削除できる。
tr -d '"'
実行結果に対して、さらにgrepコマンドで"url_q"を含む行だけを抜き出す。
grep "url_q"
結果を「url.txt」に出力する。
この作業はパイプで連結し、最後にurl.txtにリダイレクトをすることで、中間ファイルは1つだけ出力している。
実行結果

"url-q="の文字列が不要なので削除
sedコマンドで行頭にある「url_q=」の文字列を削除。
sed s/url_q=/''/
結果を「result.txt」に出力。
> result.txt
実行結果

これでようやくほしい形になった。
画像を取得
wgetコマンドで指定フォルダに画像を保存する。
-i {ファイル名}でURLを取得するファイル名を指定し、-Pで保存するディレクトリを指定する。
wget -i result.txt -P image
シェルスクリプトを作成する
ここまでのコマンドをシェルスクリプトする。
シェルスクリプトのお約束「シバン」を書く。シェルスクリプトを直接実行するためのおまじない。
#!/bin/sh
ファイル名をflicker.shにしてファイルを保存。
./flicker.shでシェルスクリプトを実行する。
実行結果

パクチーの画像がたくさん。やはりトムヤムクンとフォーあたりの画像が多い。タイかベトナムで本場のフォーが食べたい!
所感
シェルスクリプト初心者なので色々難しかったなー。できあがったシェルスクリプトを見るとなんてことないんだけど、寝る前の1時間くらいで細々とやりつつ、時にはハマったりして人に聞きながらやっていたので1wくらいかかったかな。
コマンドの引数に指定したURLに&が入っているときはエスケープするとかそういうことも覚えられたし、Linuxのキモと呼ばれているリダイレクトとパイプを体で理解できたのでやってよかった。
Linuxゲリラ戦記の#47以降で、引数を使ったりしてコードをより可変に対応していくっぽいので、このコードももう少しマシになっていく予定。