Python调用Google Drive API:如何设置下载文件的本地存储路径
问题根因
当前代码有三个直接导致文件无法找到的问题,同时缺少有序归档的实现逻辑:
- 文件名硬编码:代码中固定写入
io.FileIO('filename.extension', mode='wb'),循环遍历下载文件时,每一个云盘文件都会尝试写入同一个名称的本地文件,不仅会反复覆盖内容,还因为没有显式关闭文件句柄,内存中的下载数据无法正常刷入磁盘,部分运行环境甚至会把这类未正常关闭的临时文件放到系统不可见的临时目录下。 - 路径不固定:没有基于脚本所在位置构造存储路径,运行Python时的当前工作目录可能和你预期的脚本所在目录不一致,文件实际被写入了无关注径下,自然找不到。
- 缺少统一归档逻辑:没有提前创建专属的存储目录,所有下载动作没有固定的存储目标,很容易出现文件零散存放的问题。
实现方案
核心改动点
- 基于脚本的绝对路径构造固定存储地址,完全不受运行时工作目录的影响
- 自动创建专属的归档文件夹,目录不存在时自动初始化
- 调用Google Drive返回的文件原名称作为本地存储文件名,避免不同文件互相覆盖
- 替换手动管理的IO句柄为上下文管理器,确保下载完成后数据完整写入磁盘、文件句柄正常释放
修复后可直接运行的代码
import pickle import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from googleapiclient.http import MediaIoBaseDownload # 调整SCOPES后需要删除本地的token.pickle重新授权 SCOPES = ['https://www.googleapis.com/auth/drive.file','https://www.googleapis.com/auth/drive'] def main(): creds = None # 获取当前Python脚本所在目录的绝对路径,消除工作目录偏差 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) # 定义和脚本同目录的专属归档存储文件夹 ARCHIVE_DIR = os.path.join(SCRIPT_DIR, "google_drive_archive") # 自动创建归档目录,目录已存在时不会抛出异常 os.makedirs(ARCHIVE_DIR, exist_ok=True) if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) # 无有效凭证时走授权流程 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( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # 授权完成后保存凭证供下次使用 with open('token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('drive', 'v3', credentials=creds) # 替换为你实际要拉取的Google Drive文件夹ID TARGET_DRIVE_FOLDER_ID = '213fkrjbk324fnvbknfd' query = f"'{TARGET_DRIVE_FOLDER_ID}' in parents" response = service.files().list( q=query, spaces='drive', fields='files(id, name, parents)' ).execute() for file_meta in response['files']: request = service.files().get_media(fileId=file_meta['id']) # 拼接本地存储的绝对路径,使用云盘文件的原名称 local_save_path = os.path.join(ARCHIVE_DIR, file_meta['name']) # 用with语法自动管理文件读写,下载完成后自动刷盘、关闭句柄 with open(local_save_path, 'wb') as fh: downloader = MediaIoBaseDownload(fh, request) done = False while done is False: status, done = downloader.next_chunk() print(f"下载文件:{file_meta['name']}") print(f"下载进度:{int(status.progress() * 100)}%") print("-" * 80) if __name__ == '__main__': main()
落地效果
- 所有从指定Drive文件夹拉取的文件,都会统一存放在脚本同目录下的
google_drive_archive文件夹中,不会零散散落在其他位置 - 不管从哪个工作目录启动这个Python脚本,文件都会准确写入指定的归档目录,不存在路径偏差的问题
- 如果遇到同名文件重复下载的场景,默认会直接覆盖本地旧文件;如果需要保留历史版本,可以在拼接
local_save_path时,在文件名前追加文件ID或者下载时间戳作为区分标识
内容的提问来源于stack exchange,提问作者user14398375
相关产品推荐
相关产品推荐

