You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 17:17:47