Google Photos APIで画像をダウンロード

Created 2019年1月30日0:14
Updated 2019年1月30日0:34
Categories Python Google Photos API

前回の記事でGoogle Photos APIを使って画像の一覧を取得しましたが、その情報を使って実際に画像をダウンロードをしてみました。

準備

まず、以前の記事を参考にGoogle Photos APIにOauth2でログインして画像情報を取得できるようにしておいてください。

取得した画像情報(MediaItem)は以下のようなフォーマットになっているはずです。

{
    "id": string,
    "description": string,
    "productUrl": string,
    "baseUrl": string,
    "mimeType": string,
    "mediaMetadata": {
        object(MediaMetadata)
    },
    "contributorInfo": {
        object(ContributorInfo)
    },
    "filename": string
}

また、ドキュメントによると、baseUrlに画像サイズである=w2048-h1024を付ける事でダウンロードできるようです。

しかし、ドキュメントには書いてありませんでしたがMediaItemのbaseUrlはしばらくすると使えなくなるため、baseURLを更新するためにMediaItemsを単体で取得するAPIで最新のbaseURLを取得する必要があります。

使い方は、ログイン済みのクライアントからhttps://photoslibrary.googleapis.com/v1/mediaItems/{画像ID}にGETでアクセスするだけです。

これを行わないと、403 Forbiddenエラーが出てしまいダウンロードできません(404とかでないのがたちが悪いですよね・・・)。

コード

これを踏まえて、MediaItemの情報から画像をダウンロードするスクリプトを書きました。

以前の記事で書いたGoogle APIにログインするコードや、MediaItemsのjsonを読み込む手順などは書いていません。

from patlib import Path

media_info_url_format = "https://photoslibrary.googleapis.com/v1/mediaItems/{}"
photo_download_format = "{base}=w{width}-h{height}"

# 実際はダウンロードしたデータから読み込みます
media_item = {
    "id": "####",
    "description": "####",
    "productUrl": "####",
    "baseUrl": "####",
    "mimeType": "####",
    "mediaMetadata": {
        "width": 1920,
        "height": 1080,
        ...
    },
    ...
}

def download_photo():
    # 前回の記事で作ったスクリプトでGoogle APIにログイン
    google = login()
    # 画像IDから最新の画像情報を取得
    photo_id = media_item.get("id", None)
    response = google.get(media_info_url_format.format(photo_id))
    assert response.status_code == 200
    media_item_latest = response.json()
    # MediaItemから各種情報を取得
    base_url = media_item_latest.get("baseUrl")
    metadata = media_item_latest.get("mediaMetadata")
    filename = media_item_latest.get("filename")
    # ダウンロードURLを構成
    download_url = photo_download_format.format(
        base=base_url,
        width=metadata["width"],
        height=metadata["height"]
    )
    # ダウンロード実行
    response = google.get(download_url)
    assert response.status_code == 200
    # 保存
    write_path = Path(filename)
    write_path.write_bytes(response.content)

実行すると、その場に画像ファイルがダウンロードされます。

コメントを投稿

コメント