Created 2019年1月27日0:55
Updated 2019年1月30日0:33
Categories
Python
Google Photos API
前回の記事でGoogle Photos APIを使ってみましたが、最終的には画像をたくさんダウンロードすることが目的のためもう少し調査を行いました。
画像のダウンロード先などを含むJSONファイルをダウンロードする事を目的とします。
ただし、Google Photos APIで一度に取得できる情報は100件までなので、複数ページに分けてより多くの画像を取得します。
さらに、Google Photosには動画コンテンツも含まれるため、フィルタリングを利用して画像の情報のみを取得します。
前回の記事で作成したlogin関数などをコピーして、googleのセッションオブジェクトが取得できるようにしてください。
また、実行ディレクトリにjsonsという名前のディレクトリを作っておいてください。
import time
# APIエンドポイントは前記事とは別です
api_url = "https://photoslibrary.googleapis.com/v1/mediaItems:search"
(中略)
# 画像情報の入ったJSONを取得・保存
def get_jsons(pages=32):
# セッションオブジェクトを取得
google = login()
# POSTパラメータ
params = {
"pageSize": "100"
}
# リクエストボディ
query_filter = {
"filters": {
"mediaTypeFilter": {
"mediaTypes": [
"PHOTO"
]
}
}
}
for index in range(pages):
# リクエスト送信
response = google.post(api_url, params=params, data=json.dumps(query_filter))
assert response.status_code == 200, "Response is not 200"
res_json = response.json()
# 画像情報だけ抜き出し
items = res_json.get("mediaItems")
# 次ページのトークンを取得・設定
if "nextPageToken" in res_json:
params["pageToken"] = res_json.get("nextPageToken")
# JSONを保存
(Path("jsons") / "{}.json".format(index)).write_text(json.dumps(items, indent=4))
# 過負荷を避けるため間隔を開けてAPIを叩く
time.sleep(10)
Photos APIのデフォルトの取得件数は25件です。
変更するためにはPOSTパラメータにpageSize=100
を指定します。
Pythonのコードで実現するためには、
params = {
"pageSize": "100"
}
response = google.post(api_url, params=params)
このようにして実装します。requestsと同じですね(派生ライブラリなので当然ですが・・・)。
フィルタリングについては公式ドキュメントを参考にしました。
画像のみをフィルタリングするには、以下のJSONをリクエストボディで送れと書いてあります。
"filters": {
"mediaTypeFilter": {
"mediaTypes": [
"PHOTO"
]
}
}
リクエストボディとしてJSONを指定する場合、json.dumps
を使って平文を渡してあげます。
query_filter = {
"filters": {
"mediaTypeFilter": {
"mediaTypes": [
"PHOTO"
]
}
}
}
response = google.post(api_url, data=json.dumps(query_filter))
Google Photos APIで一度に取得できる件数は100件です。
それ以上の結果を取得する場合は、レスポンスに含まれたnextPageTokenを利用して再度リクエストを送る必要があります。
# 最初のリクエスト
response = google.post(api_url)
res_json = response.json()
params = {
"pageSize": "100",
"pageToken": res_json.get("nextPageToken")
}
# 次ページを取得
response2 = google.post(api_url, params=params)