如何使用python boto获取亚马逊S3中的唯一文件夹列表

use*_*218 28 python amazon-s3 boto

我正在使用boto和python以及amazon s3.

如果我使用

[key.name for key in list(self.bucket.list())]

然后我得到所有文件的所有密钥.

mybucket/files/pdf/abc.pdf
mybucket/files/pdf/abc2.pdf
mybucket/files/pdf/abc3.pdf
mybucket/files/pdf/abc4.pdf
mybucket/files/pdf/new/
mybucket/files/pdf/new/abc.pdf
mybucket/files/pdf/2011/
Run Code Online (Sandbox Code Playgroud)

什么是最好的方式

1. either get all folders from s3
2. or from that list just remove the file from the last and get the unique keys of folders
Run Code Online (Sandbox Code Playgroud)

我想这样做

set([re.sub("/[^/]*$","/",path) for path in mylist]
Run Code Online (Sandbox Code Playgroud)

小智 41

建立在sethwm的答案上:

要获得顶级目录:

list(bucket.list("", "/"))
Run Code Online (Sandbox Code Playgroud)

要获取以下子目录files:

list(bucket.list("files/", "/")
Run Code Online (Sandbox Code Playgroud)

等等.

  • 这很好,文档肯定会引导我朝这个方向发展,但我似乎没有获得一系列密钥.相反,我得到一个带有一个键和一个`boto.s3.prefix.Prefix()`对象的列表,我真的不知道该怎么做.有任何想法吗? (3认同)

Waw*_*zek 17

正如j1m建议的其中一条评论方法所指出的那样,返回一个前缀对象.如果您在名称/路径之后,则可以使用变量名称.例如:

import boto
import boto.s3

conn = boto.s3.connect_to_region('us-west-2')
bucket = conn.get_bucket(your_bucket)

folders = bucket.list("","/")
for folder in folders:
    print folder.name
Run Code Online (Sandbox Code Playgroud)


set*_*hwm 13

这将是一个不完整的答案,因为我不知道python或boto,但我想评论问题中的基本概念.

其中一张海报是对的:S3中没有目录的概念.只有平键/值对.许多应用程序假装某些分隔符表示目录条目.例如"/"或"\".有些应用程序就像放置一个虚拟文件一样,如果"目录"清空,你仍然可以在列表结果中看到它.

您不必总是拉下整个存储桶并在本地进行过滤.S3有一个分隔列表的概念,你可以在其中具体说明你认为你的路径分隔符("/","\","|","foobar"等),S3会将虚拟结果返回给你,类似于你想.

http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html(查看分隔符标题.)

此API将为您提供一个级别的目录.所以如果你的例子中有:

mybucket/files/pdf/abc.pdf
mybucket/files/pdf/abc2.pdf
mybucket/files/pdf/abc3.pdf
mybucket/files/pdf/abc4.pdf
mybucket/files/pdf/new/
mybucket/files/pdf/new/abc.pdf
mybucket/files/pdf/2011/
Run Code Online (Sandbox Code Playgroud)

你传入一个带有前缀""和分隔符"/"的LIST,你会得到结果:

mybucket/files/
Run Code Online (Sandbox Code Playgroud)

如果你传入一个带有前缀"mybucket/files /"和分隔符"/"的LIST,你会得到结果:

mybucket/files/pdf/
Run Code Online (Sandbox Code Playgroud)

如果你传入一个带有前缀"mybucket/files/pdf /"和分隔符"/"的LIST,你会得到结果:

mybucket/files/pdf/abc.pdf
mybucket/files/pdf/abc2.pdf
mybucket/files/pdf/abc3.pdf
mybucket/files/pdf/abc4.pdf
mybucket/files/pdf/new/
mybucket/files/pdf/2011/
Run Code Online (Sandbox Code Playgroud)

如果你想从结果集中消除pdf文件本身,那么你就是独立的.

现在你如何在python/boto中这样做我不知道.希望有办法通过.


j0n*_*nes 9

基本上S3中没有文件夹这样的东西.在内部,所有内容都存储为密钥,如果密钥名称中包含斜杠字符,则客户端可能决定将其显示为文件夹.

考虑到这一点,您应首先获取所有密钥,然后使用正则表达式过滤掉包含斜杠的路径.你现在的解决方案已经是一个良好的开端.


Edu*_*ant 8

我发现以下内容可以使用 boto3 工作:

import boto3
def list_folders(s3_client, bucket_name):
    response = s3_client.list_objects_v2(Bucket=bucket_name, Prefix='', Delimiter='/')
    for content in response.get('CommonPrefixes', []):
        yield content.get('Prefix')

s3_client = boto3.client('s3')
folder_list = list_folders(s3_client, bucket_name)
for folder in folder_list:
    print('Folder found: %s' % folder)
Run Code Online (Sandbox Code Playgroud)

参考:

  • 我可以通过将 `session.client()` 更改为 `boto3.client()` 来实现此功能 (2认同)
  • 只需将 `Prefix=''` 更改为您关心的任何前缀,它就会打印该级别的文件夹 (2认同)

Eri*_*Lee 6

我看到您已经成功建立了boto连接。如果只有一个您感兴趣的目录(如示例中提供的那样),我认为您可以使用已经通过AWS(Link)提供的前缀和分隔符。

Boto在其存储桶对象中使用此功能,并且您可以使用前缀和定界符来检索分层目录信息。bucket.list()将返回一个boto.s3.bucketlistresultset.BucketListResultSet对象。

我尝试了几种方法,如果您选择在中使用delimiter=参数bucket.list(),则返回的对象是的迭代器boto.s3.prefix.Prefix,而不是boto.s3.key.Key。换句话说,如果尝试检索应放置的子目录delimiter='\',结果将得到该prefix对象的迭代器

这两个返回的对象(前缀或键对象)都具有.name属性,因此,如果您希望目录/文件信息为字符串,则可以通过以下方式进行打印:

from boto.s3.connection import S3Connection

key_id = '...'
secret_key = '...'

# Create connection
conn = S3Connection(key_id, secret_key)

# Get list of all buckets
allbuckets = conn.get_all_buckets()
for bucket_name in allbuckets:
    print(bucket_name)

# Connet to a specific bucket
bucket = conn.get_bucket('bucket_name')

# Get subdirectory info
for key in bucket.list(prefix='sub_directory/', delimiter='/'):
    print(key.name)
Run Code Online (Sandbox Code Playgroud)

  • 虽然这个代码片段是受欢迎的,并且可能会提供一些帮助,但它会[如果它包含解释](//meta.stackexchange.com/q/114762)*如何*和*为什么*这会解决问题[大大改进] . 请记住,您是在为未来的读者回答问题,而不仅仅是现在问的人!请[编辑]您的答案以添加解释,并说明适用的限制和假设。 (2认同)