使用 Google 照片 API 时出现 403 禁止访问

Getting 403 Forbidden when using Google Photos API

对不起,英语不是我的第一语言,我的英语很烂。

我正在尝试使用 Google 照片 API 和 Python 下载我的 3000 多张照片。

首先我用这段代码下载了 MediaItems 列表。

from pathlib import Path
from requests_oauthlib import OAuth2Session
import json

api_url = "https://photoslibrary.googleapis.com/v1/mediaItems"
scope = ["https://www.googleapis.com/auth/photoslibrary.readonly"]


def save_token(token):
    token = {
        "access_token": token.get("access_token"),
        "refresh_token": token.get("refresh_token"),
        "token_type": token.get("token_type"),
        "expires_in": token.get("expires_in")
    }
    Path("token.json").write_text(json.dumps(token))


def load_token():
    token = {
        "access_token": "",
        "refresh_token": "",
        "token_type": "",
        "expires_in": "-30",
    }
    path = Path("token.json")
    if path.exists():
        token = json.loads(path.read_text())
    return token


def login():
    auth_info = json.loads(Path("credentials.json").read_text()).get("installed", None)
    assert auth_info is not None
    token = load_token()
    extras = {
        "client_id": auth_info.get("client_id"),
        "client_secret": auth_info.get("client_secret"),
    }
    google = OAuth2Session(
        auth_info.get("client_id"),
        scope=scope,
        token=token,
        auto_refresh_kwargs=extras,
        token_updater=save_token,
        auto_refresh_url=auth_info.get("token_uri"),
        redirect_uri=auth_info.get("redirect_uris")[0]
    )
    if not google.authorized:
        authorization_url, state = google.authorization_url(
            auth_info.get("auth_uri"),
            access_type="offline",
            prompt="select_account"
        )
        print("Access {} and paste code.".format(authorization_url))
        access_code = input(">>> ")
        google.fetch_token(
            auth_info.get("token_uri"),
            client_secret=auth_info.get("client_secret"),
            code=access_code
        )
        assert google.authorized
        save_token(google.token)
    return google


def test():
    google = login()
    response = google.get(api_url)
    print(response.text)


if __name__ == "__main__":
    test()

这段代码没有问题,我用 nextPageToken 下载了大约 30 json 个文件(包含 3000 张图片信息)。

之后,我尝试通过此代码下载这些图片。

photo_info_list 变量包含所有 MediaItems。

photo_download_format = "{base}=w{width}-h{height}"

def download_photos(photo_info_list):
    google = login()
    for photo_info in photo_info_list:
        photo_id = photo_info.get("id", "dummy_id")
        base_url = photo_info.get("baseUrl")
        metadata = photo_info.get("mediaMetadata")
        filename = photo_info.get("filename")
        download_url = photo_download_format.format(
            base=base_url,
            width=metadata["width"],
            height=metadata["height"]
        )
        response = google.get(download_url)
        # save_picture

此代码适用于前 162 张图片(约 270MB),但随后出现 403 forbidden 错误。

我删除了令牌并再次尝试登录程序,创建了另一个凭据但出现了同样的错误。

有谁知道是什么问题吗?

非常感谢任何建议或信息。谢谢!

baseUrls 在获取后 60 分钟后过期。根据 Google Photos APIs

的文档

You also shouldn't store baseUrls, which expire after approximately 60 minutes.

最可能的解释是您的 baseUrl 在下载过程中已过期。