使用 Python 和 Boto3 列出 S3 存储桶的目录内容?
List directory contents of an S3 bucket using Python and Boto3?
我正在尝试使用 Python 和 Boto3 列出 S3 存储桶中的所有目录。
我正在使用以下代码:
s3 = session.resource('s3') # I already have a boto3 Session object
bucket_names = [
'this/bucket/',
'that/bucket/'
]
for name in bucket_names:
bucket = s3.Bucket(name)
for obj in bucket.objects.all(): # this raises an exception
# handle obj
当我 运行 这样做时,我得到以下异常堆栈跟踪:
File "botolist.py", line 67, in <module>
for obj in bucket.objects.all():
File "/Library/Python/2.7/site-packages/boto3/resources/collection.py", line 82, in __iter__
for page in self.pages():
File "/Library/Python/2.7/site-packages/boto3/resources/collection.py", line 165, in pages
for page in pages:
File "/Library/Python/2.7/site-packages/botocore/paginate.py", line 83, in __iter__
response = self._make_request(current_kwargs)
File "/Library/Python/2.7/site-packages/botocore/paginate.py", line 155, in _make_request
return self._method(**current_kwargs)
File "/Library/Python/2.7/site-packages/botocore/client.py", line 270, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/Library/Python/2.7/site-packages/botocore/client.py", line 335, in _make_api_call
raise ClientError(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (NoSuchKey) when calling the ListObjects operation: The specified key does not exist.
列出存储桶内目录的正确方法是什么?
或者您可能想使用 boto3.client
例子
import boto3
client = boto3.client('s3')
client.list_objects(Bucket='MyBucket')
list_objects
还支持迭代结果可能需要的其他参数:Bucket、Delimiter、EncodingType、Marker、MaxKeys、Prefix
如果您有会话,请创建一个客户端并获取 CommonPrefixes
个客户端 list_objects
:
client = session.client('s3',
# region_name='eu-west-1'
)
result = client.list_objects(Bucket='MyBucket', Delimiter='/')
for obj in result.get('CommonPrefixes'):
#handle obj.get('Prefix')
可能有很多文件夹,但您可能希望从子文件夹开始。像这样的东西可以解决这个问题:
def folders(client, bucket, prefix=''):
paginator = client.get_paginator('list_objects')
for result in paginator.paginate(Bucket=bucket, Prefix=prefix, Delimiter='/'):
for prefix in result.get('CommonPrefixes', []):
yield prefix.get('Prefix')
gen_folders = folders(client, 'MyBucket')
list(gen_folders)
gen_subfolders = folders(client, 'MyBucket', prefix='MySubFolder/')
list(gen_subfolders)
我还以为你不能在桶名中有斜杠。您说您想列出一个存储桶中的所有目录,但您的代码试图列出多个存储桶中的所有内容(不一定是目录)。这些桶可能不存在(因为它们有非法名称)。所以当你 运行
bucket = s3.Bucket(name)
bucket很可能为null,后续list会失败
获取 S3 存储桶中具有特定前缀的所有对象列表的最佳方法是使用 list_objects_v2
和 ContinuationToken
来克服 1000 个对象分页限制。
import boto3
s3 = boto3.client('s3')
s3_bucket = 'your-bucket'
s3_prefix = 'your/prefix'
partial_list = s3.list_objects_v2(
Bucket=s3_bucket,
Prefix=s3_prefix)
obj_list = partial_list['Contents']
while partial_list['IsTruncated']:
next_token = partial_list['NextContinuationToken']
partial_list = s3.list_objects_v2(
Bucket=s3_bucket,
Prefix=s3_prefix,
ContinuationToken=next_token)
obj_list.extend(partial_list['Contents'])
所有这些其他回复都留下了不足之处。使用
client.list_objects()
限制您最多 1k 个结果。其余答案要么错误要么太复杂。
自己处理延续令牌是个糟糕的主意。只需使用分页器,它会为您处理该逻辑
您想要的解决方案是:
[e['Key'] for p in client.get_paginator("list_objects_v2")\
.paginate(Bucket='my_bucket')
for e in p['Contents']]
如果您的文件夹中的对象少于 1,000 个,您可以使用以下代码:
import boto3
s3 = boto3.client('s3')
object_listing = s3.list_objects_v2(Bucket='bucket_name',
Prefix='folder/sub-folder/')
我正在尝试使用 Python 和 Boto3 列出 S3 存储桶中的所有目录。
我正在使用以下代码:
s3 = session.resource('s3') # I already have a boto3 Session object
bucket_names = [
'this/bucket/',
'that/bucket/'
]
for name in bucket_names:
bucket = s3.Bucket(name)
for obj in bucket.objects.all(): # this raises an exception
# handle obj
当我 运行 这样做时,我得到以下异常堆栈跟踪:
File "botolist.py", line 67, in <module>
for obj in bucket.objects.all():
File "/Library/Python/2.7/site-packages/boto3/resources/collection.py", line 82, in __iter__
for page in self.pages():
File "/Library/Python/2.7/site-packages/boto3/resources/collection.py", line 165, in pages
for page in pages:
File "/Library/Python/2.7/site-packages/botocore/paginate.py", line 83, in __iter__
response = self._make_request(current_kwargs)
File "/Library/Python/2.7/site-packages/botocore/paginate.py", line 155, in _make_request
return self._method(**current_kwargs)
File "/Library/Python/2.7/site-packages/botocore/client.py", line 270, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/Library/Python/2.7/site-packages/botocore/client.py", line 335, in _make_api_call
raise ClientError(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (NoSuchKey) when calling the ListObjects operation: The specified key does not exist.
列出存储桶内目录的正确方法是什么?
或者您可能想使用 boto3.client
例子
import boto3
client = boto3.client('s3')
client.list_objects(Bucket='MyBucket')
list_objects
还支持迭代结果可能需要的其他参数:Bucket、Delimiter、EncodingType、Marker、MaxKeys、Prefix
如果您有会话,请创建一个客户端并获取 CommonPrefixes
个客户端 list_objects
:
client = session.client('s3',
# region_name='eu-west-1'
)
result = client.list_objects(Bucket='MyBucket', Delimiter='/')
for obj in result.get('CommonPrefixes'):
#handle obj.get('Prefix')
可能有很多文件夹,但您可能希望从子文件夹开始。像这样的东西可以解决这个问题:
def folders(client, bucket, prefix=''):
paginator = client.get_paginator('list_objects')
for result in paginator.paginate(Bucket=bucket, Prefix=prefix, Delimiter='/'):
for prefix in result.get('CommonPrefixes', []):
yield prefix.get('Prefix')
gen_folders = folders(client, 'MyBucket')
list(gen_folders)
gen_subfolders = folders(client, 'MyBucket', prefix='MySubFolder/')
list(gen_subfolders)
我还以为你不能在桶名中有斜杠。您说您想列出一个存储桶中的所有目录,但您的代码试图列出多个存储桶中的所有内容(不一定是目录)。这些桶可能不存在(因为它们有非法名称)。所以当你 运行
bucket = s3.Bucket(name)
bucket很可能为null,后续list会失败
获取 S3 存储桶中具有特定前缀的所有对象列表的最佳方法是使用 list_objects_v2
和 ContinuationToken
来克服 1000 个对象分页限制。
import boto3
s3 = boto3.client('s3')
s3_bucket = 'your-bucket'
s3_prefix = 'your/prefix'
partial_list = s3.list_objects_v2(
Bucket=s3_bucket,
Prefix=s3_prefix)
obj_list = partial_list['Contents']
while partial_list['IsTruncated']:
next_token = partial_list['NextContinuationToken']
partial_list = s3.list_objects_v2(
Bucket=s3_bucket,
Prefix=s3_prefix,
ContinuationToken=next_token)
obj_list.extend(partial_list['Contents'])
所有这些其他回复都留下了不足之处。使用
client.list_objects()
限制您最多 1k 个结果。其余答案要么错误要么太复杂。
自己处理延续令牌是个糟糕的主意。只需使用分页器,它会为您处理该逻辑
您想要的解决方案是:
[e['Key'] for p in client.get_paginator("list_objects_v2")\
.paginate(Bucket='my_bucket')
for e in p['Contents']]
如果您的文件夹中的对象少于 1,000 个,您可以使用以下代码:
import boto3
s3 = boto3.client('s3')
object_listing = s3.list_objects_v2(Bucket='bucket_name',
Prefix='folder/sub-folder/')