Python使用PyDrive上传Google Drive文件如何避免弹出浏览器页面
问题根因
你遇到的问题本质是认知偏差+配置疏漏:
- 第一版代码调用的
LocalWebserverAuth()本身就是面向个人用户的交互式授权方法,设计逻辑就是弹出浏览器让用户手动登录授权,必然有弹窗,不适合无交互场景。 - 第二版服务账号代码没有报错说明授权本身是成功的,你觉得"未达预期"大概率是两种情况:要么是工作目录残留了第一版生成的个人OAuth缓存凭证被隐式加载触发了弹窗,要么是文件上传到了服务账号的独立存储空间,你在个人网盘里找不到误以为上传失败。
- 注意:服务账号是Google云生成的独立虚拟身份,和你个人谷歌账号完全隔离,默认有自己的15G独立Drive空间,上传的文件默认存在这个独立空间里,不会出现在你的个人网盘中。
修正步骤
先清理环境
- 删除工作目录下所有PyDrive自动生成的缓存文件,比如
mycreds.txt、默认命名的credentials.json,避免旧的个人授权配置被加载。 - 确认你代码里引用的
drive2.json是服务账号的密钥文件,不是之前创建的个人OAuth 2.0客户端的密钥文件,两者格式、用途完全不同。 - 打开你个人Google Drive中要存放CSV的目标文件夹,点「共享」,把服务账号密钥JSON里
client_email字段对应的邮箱地址添加为协作者,授予「编辑者」权限。 - 记录目标文件夹的ID:打开文件夹时浏览器地址栏URL中
folders/后面的字符串就是文件夹ID,后续上传需要用到。
- 删除工作目录下所有PyDrive自动生成的缓存文件,比如
修正后的可运行代码(兼容旧版PyDrive)
显式关闭PyDrive默认的本地凭证缓存逻辑,避免加载旧的交互式授权配置:
from pydrive.auth import GoogleAuth from pydrive.drive import GoogleDrive from oauth2client.service_account import ServiceAccountCredentials gauth = GoogleAuth() # 关闭本地凭证自动读写,避免加载旧的个人OAuth缓存 gauth.settings["save_credentials"] = False gauth.settings["get_refresh_token"] = False # 遵循最小权限原则,只授予文件操作权限即可,无需全量Drive权限 scope = ["https://www.googleapis.com/auth/drive.file"] gauth.credentials = ServiceAccountCredentials.from_json_keyfile_name("drive2.json", scope) drive = GoogleDrive(gauth) # 上传到指定的个人网盘文件夹,替换下面的文件夹ID为你自己的 csv_file = drive.CreateFile({ "mimeType": "text/csv", "parents": [{"id": "替换为你记录的目标文件夹ID"}] }) csv_file.SetContentFile("test.csv") csv_file.Upload() print(f"上传完成,文件ID:{csv_file['id']}")
如果你不加
parents参数指定共享文件夹,文件会上传到服务账号的私有存储空间,你在个人网盘里看不到,且会被定期自动清理。
- 更稳定的推荐方案(使用维护中的PyDrive2)
你现在用的oauth2client库早在2017年就停止维护了,容易出现隐式配置问题,推荐替换为官方持续维护的PyDrive2分支,无交互逻辑更稳定:- 先安装依赖:
pip install pydrive2 - 对应代码:
- 先安装依赖:
from pydrive2.auth import GoogleAuth from pydrive2.drive import GoogleDrive from oauth2client.service_account import ServiceAccountCredentials gauth = GoogleAuth() gauth.credentials = ServiceAccountCredentials.from_json_keyfile_name( "drive2.json", scopes=["https://www.googleapis.com/auth/drive.file"] ) drive = GoogleDrive(gauth) csv_file = drive.CreateFile({ "mimeType": "text/csv", "parents": [{"id": "替换为你的目标文件夹ID"}] }) csv_file.SetContentFile("test.csv") csv_file.Upload() print(f"上传完成,文件访问地址:{csv_file['webViewLink']}")
验证说明
- 上述代码运行全程不会弹出浏览器授权窗口,完全无交互。
- 运行完成后打开你之前共享的目标文件夹,就能看到上传的test.csv文件,可以直接编辑、下载、管理,不需要额外转移所有权。
- 如果需要把文件所有权转移给个人账号,需要确保服务账号和个人账号属于同一个Google Workspace组织,个人免费谷歌账号不支持接收服务账号的所有权转移,普通使用场景下共享文件夹的权限已经足够。
内容的提问来源于stack exchange,提问作者Alex B
相关产品推荐
相关产品推荐

