Python Streamlit集成Google Drive API偶发下载报错问题咨询
问题根因
- 直接报错原因:异常场景下Google Drive返回了403状态码的错误响应,响应头中不存在
content-disposition字段,你直接将返回的None传入re.findall()方法,触发了类型错误。 - 403报错的核心原因:
- 你使用的Google Drive公开下载链路(
https://docs.google.com/uc?export=download)有严格的访问频率限制和流量配额,短时间内多次上传、下载操作触发了Google的临时限流,所以返回403禁止访问。 - 你每次调用
download函数都会重复执行service.permissions().create()给文件添加公开权限,重复的API请求进一步加剧了限流触发概率,同一个文件无需每次下载都重复添加权限。 - 公开下载链路未携带API认证信息,相比官方SDK自带的认证下载接口,限流阈值低很多,更容易被拦截。
- 你使用的Google Drive公开下载链路(
修复方案
1. 先做错误防御,避免类型错误
在解析响应前先校验状态码和字段存在性,代码示例:
def save_response_content(response, destination): CHUNK_SIZE = 32768 # 先校验响应状态 if response.status_code != 200: raise Exception(f"下载失败,状态码:{response.status_code}") file_size = int(response.headers.get("Content-Length", 0)) content_disposition = response.headers.get("content-disposition") # 校验字段存在性 if not content_disposition: filename = destination # 直接用传入的目标文件名即可,不需要从响应头解析 else: filename_match = re.findall("filename=\"(.+)\"", content_disposition) filename = filename_match[0] if filename_match else destination # 后续下载逻辑不变
2. 替换为官方SDK下载方法,彻底解决403限流问题
不要用requests请求公开下载链接,直接用你已经引入的MediaIoBaseDownload走认证API下载,限流阈值更高,不会出现公开链路的访问限制,修改后的下载函数示例:
def download(filename): search_result = search(query=f"name='{filename}'") file_id = search_result[0][0] request = service.files().get_media(fileId=file_id) fh = io.FileIO(filename, 'wb') downloader = MediaIoBaseDownload(fh, request) done = False while done is False: status, done = downloader.next_chunk() print(f"下载进度:{int(status.progress() * 100)}%") fh.close() # 完全不需要加公开权限,也不需要调用requests的下载逻辑
3. 优化权限逻辑
如果确实需要给文件设置公开权限,只需要在文件上传完成后调用一次permissions().create()即可,不需要每次下载都重复调用,减少无效API请求。
内容的提问来源于stack exchange,提问作者maryskal
相关产品推荐
相关产品推荐

