如何用Python Boto3获取S3桶指定目录下限定层级的内容
问题描述
我需要获取S3存储桶中指定前缀下指定层级深度的内容——比如只拿该前缀下的直接子文件和文件夹,或者n级子目录内的内容。但目前用boto3写的代码会返回该前缀下所有对象(包括深层子目录里的),而且我不想在本地解析key来过滤,请问有没有办法通过S3 API直接实现?
当前代码:
self._session = boto3.Session( aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, ) self._s3 = self._session.resource("s3") # 补全原代码遗漏的赋值 bucket = self._s3.Bucket(bucket_name) detections_contents = bucket.objects.filter(Prefix=prefix) for object_summary in detections_contents: print(object_summary.key)
解决方案
1. 获取指定前缀下的直接子项(一级深度)
S3本身没有物理文件夹,但可以通过Delimiter='/'参数让API返回前缀下的直接"文件夹"(CommonPrefixes)和直接文件(Contents),完全不需要本地过滤:
方式一:用boto3客户端(推荐,参数更直观)
s3_client = self._session.client("s3") response = s3_client.list_objects_v2( Bucket=bucket_name, Prefix=prefix, Delimiter='/' ) # 输出当前前缀下的直接文件 if 'Contents' in response: for obj in response['Contents']: print(f"文件: {obj['Key']}") # 输出当前前缀下的直接子文件夹 if 'CommonPrefixes' in response: for prefix_item in response['CommonPrefixes']: print(f"文件夹: {prefix_item['Prefix']}")
方式二:用boto3资源(Bucket对象)
如果坚持用Bucket资源接口,获取文件可以直接加Delimiter参数,但要拿到子文件夹还是需要调用客户端方法:
bucket = self._s3.Bucket(bucket_name) # 获取直接文件 for obj in bucket.objects.filter(Prefix=prefix, Delimiter='/'): print(f"文件: {obj.key}") # 获取直接子文件夹 response = bucket.meta.client.list_objects_v2(Bucket=bucket_name, Prefix=prefix, Delimiter='/') if 'CommonPrefixes' in response: for p in response['CommonPrefixes']: print(f"文件夹: {p['Prefix']}")
2. 获取n级深度的内容
S3 API没有直接的多级深度参数,但可以通过递归结合Delimiter来减少请求数据量,比一次性拉取所有对象再本地过滤高效得多:
比如获取2级深度的内容示例:
def get_n_level_objects(s3_client, bucket_name, current_prefix, current_level, max_level): if current_level > max_level: return response = s3_client.list_objects_v2( Bucket=bucket_name, Prefix=current_prefix, Delimiter='/' ) # 输出当前层级的文件 if 'Contents' in response: for obj in response['Contents']: print(f"第{current_level}级 文件: {obj['Key']}") # 递归处理下一层级的文件夹 if 'CommonPrefixes' in response and current_level < max_level: for prefix_item in response['CommonPrefixes']: print(f"第{current_level}级 文件夹: {prefix_item['Prefix']}") get_n_level_objects(s3_client, bucket_name, prefix_item['Prefix'], current_level+1, max_level) # 调用示例:获取指定前缀下2级深度的内容 s3_client = self._session.client("s3") get_n_level_objects(s3_client, bucket_name, prefix, current_level=1, max_level=2)
关键说明
Delimiter='/'是核心:它会让S3 API截断key中第一个/之后的内容,只返回当前前缀下的直接文件和子前缀(即文件夹),不会拉取深层对象。- 资源接口(Bucket)在返回文件时支持
Delimiter,但要获取子文件夹必须用客户端方法,因为资源接口没有暴露CommonPrefixes字段。 - 递归获取多级内容时,每次只请求当前层级的对象,避免了一次性拉取大量无用数据,适合大存储桶场景。
内容的提问来源于stack exchange,提问作者Gulzar
相关产品推荐
相关产品推荐

