yupaがエンジニアになるまでを記録するブログ

FjordBootCamp (フィヨルドブートキャンプ ) で学んだことや、趣味のVRに関するメモを記録していきます

Flickr APIで画像検索して検索結果の画像をダウンロードするシェルスクリプト

UNIXコマンドとかシェルスクリプトとか正規表現の勉強がてら標題のスクリプトを書いた。

主な仕様

  • 1つの引数を受け取る : ""で囲まれた検索文字列
  • 検索結果の上位10件の画像をlargeサイズでダウンロードしてimageディレクトリに保存する

環境

  • macOS High Sierra 10.13.6
  • ターミナル(bash)にて実行
  • MacにインストールされていないコマンドはHomebrewでインストールした🍺(nkfなど)

Flickr APIについて

API キーの取得

使用するにはAPIキーの取得が必要。

The App Garden on Flickr にアクセスして"Request an API Key"をクリック f:id:yu8as:20180919201212p:plain

Non-commercial(非営利)の方を選択 f:id:yu8as:20180919201540p:plain

アプリの名前と説明を入力し規約に同意したらチェックを入れてsubmit f:id:yu8as:20180919211551p:plain

するとkeyとsecretを取得できる。今回はpublicな画像を検索するので使うのはkeyのみ。 f:id:yu8as:20180919202552p:plain

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

APIキーは環境変数から読み込み

解説

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 = %`
#レスポンスの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     
.......

f:id:yu8as:20180919211332g:plain
いい感じの工場夜景の画像が10件ダウンロードされた!!

参考