树莓派使用Google API上传图片超时问题排查求助
问题分析与解决方案
核心问题:API Key认证不支持Drive上传操作
Google Drive API的developerKey(即你使用的API Key)仅适用于读取公开资源的请求,无法完成上传、修改等需要用户身份授权的操作。这是导致上传卡住超时的根本原因——你的请求因权限不足被Google服务器拦截,最终触发socket超时。
解决方案步骤
1. 改用服务账号认证(推荐)
服务账号是Google Cloud的专用身份,可授权访问指定Drive文件夹,适合无交互的设备(如树莓派):
- 登录Google Cloud Console,进入你的项目 → 「IAM与管理」→ 「服务账号」→ 创建服务账号,下载JSON密钥文件。
- 打开目标Drive文件夹,点击「共享」,将服务账号的邮箱(在JSON密钥的
client_email字段)添加为协作者,赋予「编辑」权限。 - 修改代码如下:
import os from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload from picamera import PiCamera from time import sleep from datetime import datetime from google.oauth2 import service_account # 替换为你的服务账号密钥路径和目标文件夹ID SERVICE_ACCOUNT_KEY_PATH = "/home/pi/drive-service-account.json" FOLDER_ID = "你的文件夹ID" def authenticate_drive(): SCOPES = ['https://www.googleapis.com/auth/drive.file'] credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_KEY_PATH, scopes=SCOPES) service = build('drive', 'v3', credentials=credentials) return service def take_picture(service): now = datetime.now() date_string = now.strftime("%m_%d_%y_%H%M") file_path = os.path.join(os.path.dirname(__file__), 'camera', 'pics_new', f'pic{date_string}.jpg') with PiCamera() as camera: camera.resolution = (2592, 1944) camera.framerate = 20 sleep(3) camera.capture(file_path) print(f"[{datetime.now().strftime('%H:%M:%S')}] 已拍照") print(f"[{datetime.now().strftime('%H:%M:%S')}] 开始上传至Drive") # 分块上传大文件,避免超时 file_metadata = {'name': os.path.basename(file_path), 'parents': [FOLDER_ID]} media = MediaFileUpload(file_path, mimetype='image/jpeg', chunksize=1024*1024, resumable=True) request = service.files().create(body=file_metadata, media_body=media, fields='id') response = None while response is None: status, response = request.next_chunk() if status: print(f"上传进度: {int(status.progress() * 100)}%") print("上传至Google Drive完成") def main(): service = authenticate_drive() take_picture(service) if __name__ == '__main__': main()
2. 排查网络与系统问题
如果改用服务账号后仍超时,检查以下点:
- 网络连通性:在树莓派终端执行
ping googleapis.com,确保能连通;执行curl https://www.googleapis.com/drive/v3/files测试基础访问。 - DNS设置:编辑
/etc/resolv.conf,添加nameserver 8.8.8.8(Google公共DNS),避免DNS解析失败。 - 时间同步:执行
sudo timedatectl set-ntp true开启网络时间同步,Google API对请求时间戳的准确性有要求,时间偏差过大可能导致认证失败。 - 分块上传优化:你的图片分辨率较高(约500万像素),文件体积大,分块上传(如代码中的
chunksize=1024*1024)能有效避免超时。
3. 验证API权限
- 确保Google Cloud Console中已启用Google Drive API:进入「API和服务」→ 「库」→ 搜索「Google Drive API」→ 点击启用。
- 检查服务账号的权限:确认服务账号已被添加到目标Drive文件夹的共享列表,且拥有编辑权限。
内容的提问来源于stack exchange,提问作者nkk
相关产品推荐
相关产品推荐

