使用Python调用S3 list_objects_v2无法获取存储桶完整文件列表
问题根因
无法获取全量文件的核心原因是对list_objects_v2接口的分页逻辑不熟悉:
- 该接口单次请求最多返回1000个对象,当返回结果中
IsTruncated字段值为True时,代表还有剩余对象未返回,必须携带本次返回的NextContinuationToken作为下一次请求的ContinuationToken参数循环拉取,直到IsTruncated为False才是全量结果。当前代码只发起了一次请求,自然只能拿到最多1000个对象,无法覆盖存储桶内所有文件。 - 额外说明:S3本身是扁平化对象存储,不存在真实的文件夹/子文件夹结构,所谓路径层级只是对象key中用
/分隔的前缀模拟,不需要单独遍历文件夹,只要正确完成分页拉取,就能拿到指定前缀下所有层级的对象。
修复方案
手动实现分页逻辑
import boto3 def get_s3_all_objects(bucket, prefix=""): s3 = boto3.client("s3") all_objects = [] continuation_token = None while True: req_params = {"Bucket": bucket, "Prefix": prefix} if continuation_token: req_params["ContinuationToken"] = continuation_token resp = s3.list_objects_v2(**req_params) # 处理指定前缀下无对象的空场景 if "Contents" in resp: all_objects.extend(resp["Contents"]) # 无剩余数据时终止循环 if not resp.get("IsTruncated"): break continuation_token = resp.get("NextContinuationToken") return all_objects
用boto3内置分页器(更推荐)
boto3已经封装好了分页逻辑,不需要手动维护翻页token,代码更简洁不容易出错:
import boto3 def get_s3_all_objects(bucket, prefix=""): s3 = boto3.client("s3") paginator = s3.get_paginator("list_objects_v2") all_objects = [] for page in paginator.paginate(Bucket=bucket, Prefix=prefix): if "Contents" in page: all_objects.extend(page["Contents"]) return all_objects
补充说明
- 拿到全量对象列表后,遍历每个元素的
Key属性,调用s3.get_object(Bucket=bucket, Key=obj_key)即可读取对应文件内容。 - 如果你不需要递归拉取所有子层级的对象,只想获取当前前缀下的直接文件和子文件夹,可以在请求参数中增加
Delimiter="/",此时返回结果的CommonPrefixes字段就是当前层级下的子文件夹前缀,Contents是当前层级下的直接文件。
内容的提问来源于stack exchange,提问作者Yag_r
相关产品推荐
相关产品推荐

