You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:30:57