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()
解决方案
修正权限范围
当前SCOPES设置为只读权限,但上传文件需要写入权限。将其修改为:SCOPES = ['https://www.googleapis.com/auth/drive.file']该权限仅允许脚本访问自身创建的文件,安全性更高。若需访问其他文件,可使用
https://www.googleapis.com/auth/drive(不推荐,权限过大)。修改后删除旧的token.json,重新运行脚本生成新凭证。确保凭证文件的可访问性
自动执行脚本时,需保证运行用户对token.json有读写权限,且脚本能准确定位该文件(建议使用绝对路径)。例如加载凭证时改为:creds = Credentials.from_authorized_user_file('/绝对路径/token.json', SCOPES)统一认证与上传逻辑
上传脚本使用了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实例执行上传,首次登录后后续运行将自动加载凭证,无需重复登录。
- 若继续用
检查定时执行环境
若用定时任务(如Linux cron)执行,需保证:- 脚本、文件路径均使用绝对路径
- 运行用户拥有
client_secrets.json、凭证文件及图片文件夹的访问权限 - 首次登录完成后,后续执行无需图形界面支持
内容的提问来源于stack exchange,提问作者Andreas Ravnholt
相关产品推荐
相关产品推荐

