Flickr
画像処理
Python3
urllib3

Pythonで画像データを取得してみる

More than 1 year has passed since last update.

学習履歴


■はじめに

[PythonでWebページ情報を取得してみる]では、Python による Web ページ情報の取得方法について勉強した。

今度は、Web 上にある画像を自動で取得する方法を学習しようと思う。


■Flicker の利用

Flickerというサイトから画像を取得してみる。


・Flickr API Key を取得

Flickr の画像取得は、flickr API を使用する。

[ここから] ① Get you API key の「Request an API Key」を押下し、 Yahoo US に登録して ID を取得する。

登録後、Top ページに戻ったら再び、Request an API Key からログインしてみると以下のページに入れる。

img.png

画像の通り、非商用(左)、商用(右)用の KEY があるので、左側の非商用の 

APPLY FOR A NON-COMMERCIAL KEY を選択する。

選択後、アプリケーション登録画面が表示されるので、適当な名前を入れて登録する。

スクリーンショット 2018-04-03 6.12.52.png

登録が完了したら、Key と Secret が取得できるので、大切に保管しておく。

※この後作成するプログラムに使用する

スクリーンショット 2018-04-03 6.14.48.png


・Python Flickr API の利用

Beej's Python Flickr API という Python API を使って、プログラムを組む。

そのために以下のコマンドで、必要なモジュールをインストールする必要がある。

$pip install flickrapi

※筆者は、Anaconda で仮想環境を構築していて、その中にインストールしている。


・Flicker API アクセス

画像をダウンロードする前に、取得したい画像のアドレス一覧を取得するプログラムを作成する。

しかし、その前にまずは画像を格納するフォルダを作成しておこう。

筆者は Windows 環境なので、デスクトップ上に ImageAI フォルダを作成する。

また、うさぎの画像を取得する予定なので、ImageAI フォルダの配下に rabbit フォルダ

及び getImage.py ファイルを作成した。

Desktop

LImageAI
Lrabbit
LgetImage.py

Fliker API を利用したプログラムは、以下の通りになる。


getImage.py

from flickrapi import FlickrAPI

from urllib.request import urlretrieve
from pprint import pprint
import os, time, sys

# API キーの情報

key = "上記手順で取得した key "
secret = "上記手順で取得した secret"

# 重要:リクエストを送るタイミングが短すぎると画像取得先のサーバを逼迫してしまうか、
# スパムとみなされてしまう可能性があるので、待ち時間を 1 秒間設ける。
wait_time = 1

# コマンドライン引数の 1 番目の値を取得
animalname = sys.argv[1]
# 画像を保存するディレクトリを指定
savedir = "./" + animalname

# FlickrAPI にアクセス

# FlickrAPI(キー、シークレット、データフォーマット{json で受け取る})
flickr = FlickrAPI(key, secret, format='parsed-json')
result = flickr.photos.search(
# 検索キーワード
text = animalname,
# 取得するデータ件数
per_page = 400,
# 検索するデータの種類(ここでは、写真)
media = 'photos',
# データの並び順(関連順)
sort = 'relevance',
# UI コンテンツを表示しない
safe_search = 1,
# 取得したいオプションの値(url_q->画像のアドレスが入っている情報、licence -> ライセンス情報)
extras = 'url_q, licence'
)

# 結果を表示
photos = result['photos']
pprint(photos)


コメントにも書いたが、短い期間でサーバにリクエストを送るとサーバが逼迫するか、

スパムに見なされてしまうらしいので、リクエスト間隔は 1 秒ほど開ける。

また、Flickr から画像を取得するため、FlickerAPI を使用しているが、

戻り値のオプション(extras)を指定できる。

url_q は特に重要で、画像データのアドレス情報が格納されるので、

必ず指定しよう。

プログラムの記述が終えたら、コマンドプロンプト上で実行してみよう。

以下の結果が得られるはずだ。


result.getImage.py

(test)$C\Users\*****\Desktop\imageAI> python getImage.py rabbit

{'page': 1,
'pages': 2941,
'perpage': 400,
'photo': [{'farm': 4,
'height_q': '150',
'id': '4551456285',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '12398580@N04',
'secret': '5d84e71f7a',
'server': '3521',
'title': 'Rabbit',
'url_q': 'https://farm4.staticflickr.com/3521/4551456285_5d84e71f7a_q.jpg',
'width_q': '150'},
{'farm': 4,
'height_q': '150',
'id': '2675343973',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '12305978@N08',
'secret': 'a5d35fafe9',
'server': '3148',
'title': 'Rabbit',
'url_q': 'https://farm4.staticflickr.com/3148/2675343973_a5d35fafe9_q.jpg',
'width_q': '150'},
{'farm': 3,
'height_q': '150',
'id': '4038258875',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '27717684@N00',
'secret': '793df0d6d1',
'server': '2618',
'title': 'Rabbit',
'url_q': 'https://farm3.staticflickr.com/2618/4038258875_793df0d6d1_q.jpg',
'width_q': '150'},
{'farm': 4,
'height_q': '150',
'id': '2675344021',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '12305978@N08',
'secret': '443093615b',
'server': '3089',
'title': 'Rabbit',
'url_q': 'https://farm4.staticflickr.com/3089/2675344021_443093615b_q.jpg',
'width_q': '150'},
{'farm': 3,
'height_q': '150',
'id': '4511998074',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '22541812@N03',
'secret': '3cf5c38c70',
'server': '2032',
'title': 'rabbit',
'url_q': 'https://farm3.staticflickr.com/2032/4511998074_3cf5c38c70_q.jpg',
'width_q': '150'},
{'farm': 8,
'height_q': '150',
'id': '8737837401',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '66070376@N06',
'secret': '7ea0758fcd',
'server': '7285',
'title': 'Rabbit',
'url_q': 'https://farm8.staticflickr.com/7285/8737837401_7ea0758fcd_q.jpg',
'width_q': '150'},
{'farm': 5,
'height_q': '150',
'id': '4520875292',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '49284136@N03',
'secret': '27622d99ab',
'server': '4005',
'title': 'Rabbit',
'url_q': 'https://farm5.staticflickr.com/4005/4520875292_27622d99ab_q.jpg',
'width_q': '150'},
{'farm': 1,
'height_q': '150',
'id': '502822060',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '61926883@N00',
'secret': '34cbaef0c1',
'server': '224',
'title': 'Rabbit',
'url_q': 'https://farm1.staticflickr.com/224/502822060_34cbaef0c1_q.jpg',
'width_q': '150'},
{'farm': 3,
'height_q': '150',
'id': '3845178671',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '60609999@N00',
'secret': '6755f2100b',
'server': '2009',
'title': 'Rabbit',
'url_q': 'https://farm3.staticflickr.com/2009/3845178671_6755f2100b_q.jpg',
'width_q': '150'},
{'farm': 3,
'height_q': '150',
'id': '14047099969',
'isfamily': 0,
'isfriend': 0,
'ispublic': 1,
'owner': '62410592@N04',
'secret': '07f1cd531e',
'server': '2922',
'title': 'Rabbits',
'url_q': 'https://farm3.staticflickr.com/2922/14047099969_07f1cd531e_q.jpg',
'width_q': '150'},

...... 省略


上記結果の url_q が画像のアドレスになっていて、後はこのアドレスから urllib を

使って画像データを取得する。


・画像データを取得

先程作成したプログラムにアドレスから画像データを取得するプログラムを追加する。


getImage.py

from flickrapi import FlickrAPI

from urllib.request import urlretrieve
from pprint import pprint
import os, time, sys

# API キーの情報
key = "上記手順で取得した key "
secret = "上記手順で取得した secret"

# 重要:リクエストを送るタイミングが短すぎると画像取得先のサーバを逼迫してしまうか、
# スパムとみなされてしまう可能性があるので、待ち時間を 1 秒間設ける。
wait_time = 1

# コマンドライン引数の 1 番目の値を取得
animalname = sys.argv[1]
# 画像を保存するディレクトリを指定
savedir = "./" + animalname

# FlickrAPI にアクセス

# FlickrAPI(キー、シークレット、データフォーマット{json で受け取る})
flickr = FlickrAPI(key, secret, format='parsed-json')
result = flickr.photos.search(
# 検索キーワード
text = animalname,
# 取得するデータ件数
per_page = 400,
# 検索するデータの種類(ここでは、写真)
media = 'photos',
# データの並び順(関連順)
sort = 'relevance',
# UI コンテンツを表示しない
safe_search = 1,
# 取得したいオプションの値(url_q->画像のアドレスが入っている情報、licence -> ライセンス情報)
extras = 'url_q, licence'
)

# 結果を表示
photos = result['photos']
# pprint(photos)

# 追記
for photo in photos['photo']:
url_q = photo['url_q']
filepath = savedir + '/' + photo['id'] + '.jpg'
# ファイルが重複していたらスキップする
if os.path.exists(filepath): continue
# データをダウンロードする
urlretrieve(url_q, filepath)
# 重要:サーバを逼迫しないように 1 秒待つ
time.sleep(wait_time)


{# 追記} としたところが、画像をダウンロードするプログラムだ。

プログラムを書き終えたら、アドレス一覧を取得した時と同じように

コマンドプロンプト上から python getImage.py rabbit と打つと画像データがダウンロードされる。

img.png


■まとめ

・Python による画像取得方法を学んだ。

・画像を取得する Flickr は便利だと思った。