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

Google Drive API脚本每次运行均需重新认证的问题求助

问题描述

我写了一个将图片上传到Google Drive文件夹的脚本,本地运行正常,但需要每两周自动执行一次。现在每次运行Google都要求登录,没法保留首次登录的会话。

上传文件脚本

def upload_files():
    upload_files_list = []
    for element in os.listdir("billeder"):
        upload_files_list.append("/root/billeder/" + element)

    for upload_file in upload_files_list:
        gfile = drive.CreateFile({'parents': [{'id': 'folder_id_here'}]})
        # 读取文件并设置为当前实例内容
        gfile.SetContentFile(upload_file)
        gfile.Upload()  # 上传文件

认证脚本

from __future__ import print_function

import os.path

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# 修改权限范围后,请删除token.json文件
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']


def main():
    """演示Drive v3 API基础用法
    打印用户可访问的前10个文件的名称和ID
    """
    creds = None
    # token.json文件存储用户的访问令牌和刷新令牌,首次授权流程完成后自动创建
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # 无有效凭证时,引导用户登录
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'client_secrets.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # 保存凭证供下次使用
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    try:
        service = build('drive', 'v3', credentials=creds)

        # 调用Drive v3 API
        results = service.files().list(
            pageSize=10, fields="nextPageToken, files(id, name)").execute()
        items = results.get('files', [])

        if not items:
            print('未找到文件。')
            return
        print('文件列表:')
        for item in items:
            print(u'{0} ({1})'.format(item['name'], item['id']))
    except HttpError as error:
        # TODO(开发者) - 处理Drive API错误
        print(f'发生错误:{error}')


if __name__ == '__main__':
    main()
解决方案
  1. 修正权限范围
    当前SCOPES设置为只读权限,但上传文件需要写入权限。将其修改为:

    SCOPES = ['https://www.googleapis.com/auth/drive.file']
    

    该权限仅允许脚本访问自身创建的文件,安全性更高。若需访问其他文件,可使用https://www.googleapis.com/auth/drive(不推荐,权限过大)。修改后删除旧的token.json,重新运行脚本生成新凭证。

  2. 确保凭证文件的可访问性
    自动执行脚本时,需保证运行用户对token.json有读写权限,且脚本能准确定位该文件(建议使用绝对路径)。例如加载凭证时改为:

    creds = Credentials.from_authorized_user_file('/绝对路径/token.json', SCOPES)
    
  3. 统一认证与上传逻辑
    上传脚本使用了pydrive库的drive.CreateFile,但认证脚本用的是官方google-api-python-client,两者不兼容。需统一为一种方式:

    • 若继续用pydrive,可修改认证逻辑保存会话:
      from pydrive.auth import GoogleAuth
      from pydrive.drive import GoogleDrive
      
      gauth = GoogleAuth()
      # 加载已保存的凭证,无凭证则触发登录
      gauth.LoadCredentialsFile("mycreds.txt")
      if gauth.credentials is None:
          gauth.LocalWebserverAuth()
      elif gauth.access_token_expired:
          gauth.Refresh()
      else:
          gauth.Authorize()
      # 保存凭证到文件
      gauth.SaveCredentialsFile("mycreds.txt")
      
      drive = GoogleDrive(gauth)
      
      用此drive实例执行上传,首次登录后后续运行将自动加载凭证,无需重复登录。
  4. 检查定时执行环境
    若用定时任务(如Linux cron)执行,需保证:

    • 脚本、文件路径均使用绝对路径
    • 运行用户拥有client_secrets.json、凭证文件及图片文件夹的访问权限
    • 首次登录完成后,后续执行无需图形界面支持

内容的提问来源于stack exchange,提问作者Andreas Ravnholt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:05:20