Flickr APIで画像検索して検索結果の画像をダウンロードするシェルスクリプト
UNIXコマンドとかシェルスクリプトとか正規表現の勉強がてら標題のスクリプトを書いた。
主な仕様
- 1つの引数を受け取る : ""で囲まれた検索文字列
- 検索結果の上位10件の画像をlargeサイズでダウンロードしてimageディレクトリに保存する
環境
Flickr APIについて
API キーの取得
使用するにはAPIキーの取得が必要。
The App Garden on Flickr にアクセスして"Request an API Key"をクリック
Non-commercial(非営利)の方を選択
アプリの名前と説明を入力し規約に同意したらチェックを入れてsubmit
するとkeyとsecretを取得できる。今回はpublicな画像を検索するので使うのはkeyのみ。
APIで画像検索してみる
Flickr Services: Flickr API: flickr.photos.searchを参考に以下のようにURLを組み立てる
https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=取得したAPIキー&format=rest&text=検索キーワード&extras=url_l
最後のextras=url_l
は検索結果にlサイズの画像のリンクを含めるように指定している。
試しに、検索ワード"工場夜景"で検索してみると・・・
<rsp stat="ok"> <photos page="1" pages="54" perpage="100" total="5376"> <photo id="44608553832" owner="124733612@N05" secret="8347c94989" server="1876" farm="2" title="[HDR]夜のタンク" ispublic="1" isfriend="0" isfamily="0" url_l="https://farm2.staticflickr.com/1876/44608553832_8347c94989_b.jpg" height_l="681" width_l="1024"/> <photo id="43856049064" owner="125446885@N04" secret="a3ea615f37" server="1848" farm="2" title="片貝花火" ispublic="1" isfriend="0" isfamily="0" url_l="https://farm2.staticflickr.com/1848/43856049064_a3ea615f37_b.jpg" height_l="683" width_l="1024"/> <photo id="44485653892" owner="124733612@N05" secret="bcb27f8077" server="1872" farm="2" title="新日鐵住金君津製鐵所の夜景" ispublic="1" isfriend="0" isfamily="0" url_l="https://farm2.staticflickr.com/1872/44485653892_bcb27f8077_b.jpg" height_l="681" width_l="1024"/> <photo id="44499188271" owner="143665393@N04" secret="bc0d8ed0ce" server="1881" farm="2" title="Inaba port line, Yokkaichi, Japan" ispublic="1" isfriend="0" isfamily="0" url_l="https://farm2.staticflickr.com/1881/44499188271_bc0d8ed0ce_b.jpg" height_l="1024" width_l="683"/> ...
検索結果の上位100件のリストがxmlで返ってくる。
値には画像の直リンが含まれているのでこのURLのみのリストに整形してwgetに渡して画像をダウンロードするというスクリプトを組む。
コード
2018.9.21 : 一時ファイルをmktempで作成されるファイルに変更した
#!/bin/sh if [ -z $1 ]; then echo "検索キーワードを入れてください" echo "以下に例を示します" echo "\$ ${0} \"GT-R R35\"" exit fi keyword=$1 # 文字列をエンコード=を%に置換 keyword=`echo $keyword | nkf -wMQ | tr = %` # 一時ファイルを作成↲ res=`mktemp`↲ list_url=`mktemp` #レスポンスを一時ファイルへ curl "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=${FLICKR_API_KEY}&format=rest&text=${keyword}&extras=url_l" > $res #レスポンスのstatusを取得 status=`cat $res | grep "<rsp stat=" | sed -e 's/<rsp stat="//g' -e 's/">//g'` if [ $status != "ok" ]; then echo "画像リストを取得できませんでした" exit fi ## レスポンスのxmlから画像urlのみを切り取って最初の10行を一時ファイルに保存 cat $res | grep "url_l" | sed -e 's/^.*url_l="//g' -e 's/".*$//g' | head > $list_url ## /imageディレクトリがなければ作成 [ ! -e image ] && mkdir image ## wgetでimageディレクトリ内に画像ダウンロード wget -T 30 -t 1 -i list_url.txt -P image rm $res rm $list_url
解説
if [ -z $1 ]; then
-z
: 文字列比較演算子 文字列の長さが0であれば真$1
: シェルスクリプト実行時に与えられた引数。1つめは$1
、2つ目は$2
というようにインクリメントされていく;
: 1行に複数のコマンドを書く際に区切りとなる文字
[
もコマンドのひとつなので前後に空白が必要
echo "\$ ${0} \"GT-R R35\""
${0}
:$0
は実行時のコマンド名が設定される変数。文字列中なので{}で囲っている
# 文字列をエンコード=を%に置換 keyword=`echo $keyword | nkf -wMQ | tr = %`
nkf -wMQ
: MIME quotedに変換しUTF-8で出力tr = %
: "="を"%"に置換
#レスポンスのstatusを取得 status=`cat res.txt | grep "<rsp stat=" | sed -e 's/<rsp stat="//g' -e 's/">//g'`
sed -e 's/<rsp stat="//g' -e 's/">//g'
: ''のダブルクォーテーション前後を空文字に置換しstatの値を取り出している
## レスポンスのxmlから画像urlのみを切り取って最初の10行を一時ファイルに保存 cat res.txt | grep "url_l" | sed -e 's/^.*url_l="//g' -e 's/".*$//g' | head > list_url.txt
s/^.*url_l="//g
: 行の先頭からurl_l="
までを空文字に置換s/".*$//g
: 最初の"
から行末までを空文字に置換 (URLの切り取り、もっといい方法がある気がする・・・)
## /imageディレクトリがなければ作成 [ ! -e image ] && mkdir image
!
: 否定-e image
: imageファイル(ディレクトリ)が有れば真
## wgetでimageディレクトリ内に画像ダウンロード wget -T 30 -t 1 -i list_url.txt -P image
-T 30
: タイム・アウトするまでの秒数。今回は30秒-t 1
: リトライする回数。今回は1回-i list_url.txt
: URLをファイルから読み込み-P image
: ファイルをダウンロードするディレクトリを指定
実行結果
検索ワードは"工場夜景"
$ ./flickrsearch.sh "工場夜景" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 26802 100 26802 0 0 37967 0 --:--:-- --:--:-- --:--:-- 37963 --2018-09-19 21:07:25-- https://farm2.staticflickr.com/1844/29805641047_779f870a25_b.jpg farm2.staticflickr.com (farm2.staticflickr.com) をDNSに問いあわせています... 74.6.47.80 farm2.staticflickr.com (farm2.staticflickr.com)|74.6.47.80|:443 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 461874 (451K) [image/jpeg] `image/29805641047_779f870a25_b.jpg' に保存中 29805641047_779f870a25_b.jpg 100%[=================================================>] 451.05K 443KB/s 時間 1.0s .......
いい感じの工場夜景の画像が10件ダウンロードされた!!