列出带有boto3的存储桶的内容


Answers:


241

查看内容的一种方法是:

for my_bucket_object in my_bucket.objects.all():
    print(my_bucket_object)

1
我可以使用boto3在存储桶中的特定路径下或特定分隔符下获取密钥吗?
拉胡尔KP 2015年

109
您应该能够说出来mybucket.objects.filter(Prefix='foo/bar'),它只会列出具有该前缀的对象。您还可以传递Delimiter参数。
garnaat 2015年

3
不与boto3 AttributeError的工作:“S3”对象没有属性“对象”

2
@garnaat您的评论中提到filter方法确实对我有所帮助(我的代码最终变得更加简单和快捷)-谢谢!
爱德华·迪克森

24
我建议不要将其object用作变量名,因为它会影响全局类型object
奥兰(Oliland)'18年

100

这类似于“ ls”,但是它没有考虑前缀文件夹约定,并且会列出存储桶中的对象。它留给阅读器以过滤掉作为键名称一部分的前缀。

在Python 2中:

from boto.s3.connection import S3Connection

conn = S3Connection() # assumes boto.cfg setup
bucket = conn.get_bucket('bucket_name')
for obj in bucket.get_all_keys():
    print(obj.key)

在Python 3中:

from boto3 import client

conn = client('s3')  # again assumes boto.cfg setup, assume AWS S3
for key in conn.list_objects(Bucket='bucket_name')['Contents']:
    print(key['Key'])

39
如果您也想使用前缀,则可以这样操作:conn.list_objects(Bucket='bucket_name', Prefix='prefix_string')['Contents']
markonovak

13
这仅列出前1000个键。在文档字符串中:“返回存储桶中的部分或全部(最多1000个)对象。” 另外,建议您使用list_objects_v2而不是list_objects(尽管这也只会返回前1000个键)。
Brett Widmeier

3
应该使用分页器
v25

44

我假设您已经分别配置了身份验证。

import boto3
s3 = boto3.resource('s3')

my_bucket = s3.Bucket('bucket_name')

for file in my_bucket.objects.all():
    print(file.key)

30

如果要传递ACCESS和SECRET密钥(由于不安全,则不应该这样做):

from boto3.session import Session

ACCESS_KEY='your_access_key'
SECRET_KEY='your_secret_key'

session = Session(aws_access_key_id=ACCESS_KEY,
                  aws_secret_access_key=SECRET_KEY)
s3 = session.resource('s3')
your_bucket = s3.Bucket('your_bucket')

for s3_file in your_bucket.objects.all():
    print(s3_file.key)

13
这比在〜/ .aws / credentials中具有凭据文件安全性低。虽然这是一个有效的解决方案。
nu everest

6
这将需要将秘密提交给源代码控制。不好。
jan groth

2
此答案未添加任何有关列出对象的API /机制的信息,同时添加了不相关的身份验证方法,该方法对于所有boto资源都是通用的,并且是一种
不安全的

在有关安全性的答案中添加了免责声明。
rjurney

如果密钥是由诸如Vault(Hashicorp)之类的密钥/秘密管理系统提供的,那岂不是仅将凭证文件放在〜/ .aws / credentials中会更好吗?
SunnyAk

25

为了处理大型键列表(即,当目录列表大于1000个项目时),我使用以下代码来累加具有多个列表的键值(即文件名)(这要归功于上述第一行的Amelio)。代码适用于python3:

    from boto3  import client
    bucket_name = "my_bucket"
    prefix      = "my_key/sub_key/lots_o_files"

    s3_conn   = client('s3')  # type: BaseClient  ## again assumes boto.cfg setup, assume AWS S3
    s3_result =  s3_conn.list_objects_v2(Bucket=bucket_name, Prefix=prefix, Delimiter = "/")

    if 'Contents' not in s3_result:
        #print(s3_result)
        return []

    file_list = []
    for key in s3_result['Contents']:
        file_list.append(key['Key'])
    print(f"List count = {len(file_list)}")

    while s3_result['IsTruncated']:
        continuation_key = s3_result['NextContinuationToken']
        s3_result = s3_conn.list_objects_v2(Bucket=bucket_name, Prefix=prefix, Delimiter="/", ContinuationToken=continuation_key)
        for key in s3_result['Contents']:
            file_list.append(key['Key'])
        print(f"List count = {len(file_list)}")
    return file_list

20

我的s3 keys实用程序函数本质上是@Hephaestus答案的优化版本:

import boto3


s3_paginator = boto3.client('s3').get_paginator('list_objects_v2')


def keys(bucket_name, prefix='/', delimiter='/', start_after=''):
    prefix = prefix[1:] if prefix.startswith(delimiter) else prefix
    start_after = (start_after or prefix) if prefix.endswith(delimiter) else start_after
    for page in s3_paginator.paginate(Bucket=bucket_name, Prefix=prefix, StartAfter=start_after):
        for content in page.get('Contents', ()):
            yield content['Key']

在我的测试(boto3 1.9.84)中,它比等效(但更简单)的代码快得多:

import boto3


def keys(bucket_name, prefix='/', delimiter='/'):
    prefix = prefix[1:] if prefix.startswith(delimiter) else prefix
    bucket = boto3.resource('s3').Bucket(bucket_name)
    return (_.key for _ in bucket.objects.filter(Prefix=prefix))

由于S3保证UTF-8二进制排序结果start_after因此对第一个函数进行了优化。


到目前为止,这是最好的答案。当我向下滚动时,我只是在修改@Hephaestus的答案(因为它是最高的)。这应该是公认的答案,并且应该因简洁而获得加分。我要补充一点,第二个代码中的生成器需要包装起来list()以返回文件列表。
理查德D

@RichardD两个结果都返回生成器。我使用此代码定位的许多存储桶具有比代码执行程序一次可以处理的内存更多的键(例如,AWS Lambda);我更喜欢在生成密钥时使用它们。
肖恩·萨默斯,

6

一种更简化的方法,而不是通过for循环进行遍历,您还可以仅打印包含S3存储桶中所有文件的原始对象:

session = Session(aws_access_key_id=aws_access_key_id,aws_secret_access_key=aws_secret_access_key)
s3 = session.resource('s3')
bucket = s3.Bucket('bucket_name')

files_in_s3 = bucket.objects.all() 
#you can print this iterable with print(list(files_in_s3))

3
@petezurich,能否请您解释一下为什么这么小的修改-在回答开头用大写的“ A”代替“ a”会使我的声誉降低-2,但是我认为您和我都同意这不仅与您的纠正根本无关,而且实际上很琐碎,您不是这样说的吗?请专注于内容,而不是幼稚的修订,最有责任感的男孩
Daniel Vieira

这是两种不同的相互作用。1.我编辑了您的答案,即使是较小的拼写错误,也建议您这样做。我同意,小事和琐事之间的界限是模棱两可的。我不会拒绝任何帖子的投票,因为我看到了错误,但在这种情况下却没有。我只是解决了我看到的所有错误。
petezurich

2.我不赞成你的回答,因为你写的files_in_s3是“列表对象”。Python中没有这样的东西。相反,这是一个可迭代的过程,我无法使您的代码正常工作,因此被否决了。比我发现错误并明白您的意思了,但无法撤消我的反对意见。
petezurich

5
@petezurich没问题,理解您的观点,只有一件事,在Python中,列表是对象,因为python中的几乎所有东西都是对象,然后它也随之产生一个列表也是可迭代的,但首先,它是一个目的!这就是为什么我不理解您的不赞成票的原因-您不赞成某项正确且有效的代码。无论如何,感谢您的致歉和一切
Daniel Vieira

1
@petezurich Python中的所有内容都是一个对象。“列表对象”是完全可以接受的。
Zach Garwood

4

对象摘要:

ObjectSummary附带有两个标识符:

  • bucket_name

boto3 S3:ObjectSummary

AWS S3文档中有关对象密钥的更多信息:

对象键:

创建对象时,请指定键名,该键名唯一标识存储桶中的对象。例如,在Amazon S3控制台(请参阅AWS管理控制台)中,突出显示存储桶时,将显示存储桶中的对象列表。这些名称是对象键。密钥的名称是一系列Unicode字符,其UTF-8编码最长为1024个字节。

Amazon S3数据模型是一个平面结构:创建一个存储桶,该存储桶存储对象。没有子桶或子文件夹的层次结构;但是,您可以像Amazon S3控制台一样使用键名前缀和定界符来推断逻辑层次结构。Amazon S3控制台支持文件夹的概念。假设您的存储桶(由管理员创建)具有四个带有以下对象键的对象:

开发/项目1.xls

财务/声明1.pdf

私人/taxdocument.pdf

s3-dg.pdf

参考:

AWS S3:对象密钥

这是一些示例代码,演示了如何获取存储桶名称和对象密钥。

例:

import boto3
from pprint import pprint

def main():

    def enumerate_s3():
        s3 = boto3.resource('s3')
        for bucket in s3.buckets.all():
             print("Name: {}".format(bucket.name))
             print("Creation Date: {}".format(bucket.creation_date))
             for object in bucket.objects.all():
                 print("Object: {}".format(object))
                 print("Object bucket_name: {}".format(object.bucket_name))
                 print("Object key: {}".format(object.key))

    enumerate_s3()


if __name__ == '__main__':
    main()

3

我只是这样做,包括身份验证方法:

s3_client = boto3.client(
                's3',
                aws_access_key_id='access_key',
                aws_secret_access_key='access_key_secret',
                config=boto3.session.Config(signature_version='s3v4'),
                region_name='region'
            )

response = s3_client.list_objects(Bucket='bucket_name', Prefix=key)
if ('Contents' in response):
    # Object / key exists!
    return True
else:
    # Object / key DOES NOT exist!
    return False

2
#To print all filenames in a bucket
import boto3

s3 = boto3.client('s3')

def get_s3_keys(bucket):

    """Get a list of keys in an S3 bucket."""
    resp = s3.list_objects_v2(Bucket=bucket)
    for obj in resp['Contents']:
      files = obj['Key']
    return files


filename = get_s3_keys('your_bucket_name')

print(filename)

#To print all filenames in a certain directory in a bucket
import boto3

s3 = boto3.client('s3')

def get_s3_keys(bucket, prefix):

    """Get a list of keys in an S3 bucket."""
    resp = s3.list_objects_v2(Bucket=bucket, Prefix=prefix)
    for obj in resp['Contents']:
      files = obj['Key']
      print(files)
    return files


filename = get_s3_keys('your_bucket_name', 'folder_name/sub_folder_name/')

print(filename)

两个“ get_s3_keys”仅返回最后一个键。
Alexey Vazhnov

1

在上述注释之一中,@ Hephaeastus的代码几乎没有修改,编写了以下方法以列出给定路径中的文件夹和对象(文件)。与s3 ls命令类似。

from boto3 import session

def s3_ls(profile=None, bucket_name=None, folder_path=None):
    folders=[]
    files=[]
    result=dict()
    bucket_name = bucket_name
    prefix= folder_path
    session = boto3.Session(profile_name=profile)
    s3_conn   = session.client('s3')
    s3_result =  s3_conn.list_objects_v2(Bucket=bucket_name, Delimiter = "/", Prefix=prefix)
    if 'Contents' not in s3_result and 'CommonPrefixes' not in s3_result:
        return []

    if s3_result.get('CommonPrefixes'):
        for folder in s3_result['CommonPrefixes']:
            folders.append(folder.get('Prefix'))

    if s3_result.get('Contents'):
        for key in s3_result['Contents']:
            files.append(key['Key'])

    while s3_result['IsTruncated']:
        continuation_key = s3_result['NextContinuationToken']
        s3_result = s3_conn.list_objects_v2(Bucket=bucket_name, Delimiter="/", ContinuationToken=continuation_key, Prefix=prefix)
        if s3_result.get('CommonPrefixes'):
            for folder in s3_result['CommonPrefixes']:
                folders.append(folder.get('Prefix'))
        if s3_result.get('Contents'):
            for key in s3_result['Contents']:
                files.append(key['Key'])

    if folders:
        result['folders']=sorted(folders)
    if files:
        result['files']=sorted(files)
    return result

这将列出给定路径中的所有对象/文件夹。默认情况下,Folder_path可以保留为None,方法将列出存储桶根的立即内容。


0

这是解决方案

导入boto3

s3 = boto3.resource('s3')

BUCKET_NAME ='您的S3存储桶名称,例如'deletemetesting11'

allFiles = s3.Bucket(BUCKET_NAME).objects.all()

对于allFiles中的文件:print(file.key)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.