如何从他人GCS Bucket逐个下载文件至Colab/Python并解决认证错误
解决Google Cloud Storage Python库认证错误及逐个下载文件问题
错误原因分析
你遇到的RefreshError是因为Google Cloud Python客户端库默认尝试从Google Compute Engine(GCE)元数据服务获取认证凭证,但当前环境(比如本地机器或未正确配置的Colab)没有这个服务,导致请求失败。而你能用gcloud storage cp命令,说明你的环境已经有有效的认证(比如Colab关联了Google账号,本地gcloud已登录),只是Python库没正确复用这个认证。
解决方案
根据你的使用环境(Colab/本地),选择对应的处理方式:
1. Colab环境下的快速修复
在Colab中,你已经通过gcloud命令完成了认证,可以让Python客户端直接复用这个认证,或者通过Colab的内置认证工具获取凭证:
方法一:复用gcloud的应用默认凭证
修改你的代码,让客户端使用gcloud的默认凭证:
from google.cloud import storage from google.auth import default # 获取gcloud的默认凭证 credentials, project_id = default() # 用凭证初始化客户端 client = storage.Client(credentials=credentials, project=project_id) # 注意:bucket_name只需要填桶名,不需要后面的路径 bucket_name = "jk***_storage" bucket = client.get_bucket(bucket_name) # 列出指定路径下的所有文件(对应你之前批量下载的路径) prefix = "openimg_v6_filtered/filtered_images/" blobs = bucket.list_blobs(prefix=prefix) # 逐个下载示例 save_dir = "./dataImg/" import os os.makedirs(save_dir, exist_ok=True) for blob in blobs: # 跳过目录(如果有的话) if blob.name.endswith('/'): continue # 构建本地保存路径 local_path = os.path.join(save_dir, os.path.basename(blob.name)) # 下载文件 blob.download_to_filename(local_path) print(f"已下载:{blob.name} -> {local_path}")
方法二:使用Colab的内置认证
如果上面的方法不行,先运行Colab的认证命令:
from google.colab import auth auth.authenticate_user() from google.cloud import storage client = storage.Client() # 后续代码和上面一致 bucket_name = "jk***_storage" bucket = client.get_bucket(bucket_name) prefix = "openimg_v6_filtered/filtered_images/" blobs = bucket.list_blobs(prefix=prefix)
2. 本地环境下的修复
如果你是在本地机器运行代码,需要确保Python客户端能获取到有效的认证凭证:
方法一:使用gcloud的应用默认凭证
- 确保你已经通过
gcloud auth login命令登录了你的Google账号 - 运行
gcloud auth application-default login生成应用默认凭证 - 然后直接使用修正后的代码(bucket名仅填
jk***_storage,路径用prefix参数指定),客户端会自动加载这个凭证
方法二:使用服务账号密钥文件
如果对方提供了服务账号密钥文件(.json格式):
from google.cloud import storage # 指定服务账号密钥文件路径 client = storage.Client.from_service_account_json('/path/to/your/service-account-key.json') bucket_name = "jk***_storage" bucket = client.get_bucket(bucket_name) prefix = "openimg_v6_filtered/filtered_images/" blobs = bucket.list_blobs(prefix=prefix) # 逐个下载代码和前面一致
关键注意点
- bucket_name的正确写法:你之前写的
"jk***_storage/openimg_v6_filtered"是错误的,bucket名只是jk***_storage,后面的路径是blob的前缀,需要用prefix参数指定 - 因为你只有部分资源的访问权限,
list_blobs只会返回你有权限访问的文件,不用担心超出权限范围
内容的提问来源于stack exchange,提问作者Jeet Sensarma
相关产品推荐
相关产品推荐

