s3网址 - 获取存储桶名称和路径

Lij*_*hew 32 python boto3

我有一个变量,它有aws s3 url

s3://bucket_name/folder1/folder2/file1.json
Run Code Online (Sandbox Code Playgroud)

我想在变量中获取bucket_name并在另一个变量中使用/folder1/folder2/file1.json.我尝试了正则表达式,可以得到如下所示的bucket_name,不确定是否有更好的方法.

m = re.search('(?<=s3:\/\/)[^\/]+', 's3://bucket_name/folder1/folder2/file1.json')
print(m.group(0))
Run Code Online (Sandbox Code Playgroud)

我怎么得到其余的ie - folder1/folder2/file1.json?

我检查了是否有boto3功能从URL中提取bucket_name和key,但找不到它.

kic*_*hik 54

由于它只是一个普通的URL,因此您可以使用它urlparse来获取URL的所有部分.

>>> from urlparse import urlparse
>>> o = urlparse('s3://bucket_name/folder1/folder2/file1.json', allow_fragments=False)
>>> o
ParseResult(scheme='s3', netloc='bucket_name', path='/folder1/folder2/file1.json', params='', query='', fragment='')
>>> o.netloc
'bucket_name'
>>> o.path
'/folder1/folder2/file1.json'
Run Code Online (Sandbox Code Playgroud)

您可能必须从密钥中删除开始斜杠,如下一个答案所示.

o.path.lstrip('/')
Run Code Online (Sandbox Code Playgroud)

随着Python 3 urlparse移动到urllib.parse如此使用:

from urllib.parse import urlparse
Run Code Online (Sandbox Code Playgroud)

  • 但是请注意,如果文件名中包含#,在这种情况下,o.path将不包含完整密钥。urlparse('s3:// bucket_name / file#2.json')。path =='/ file' (2认同)
  • 您可以使用“allow_fragments=False”。查看更新的答案。如果你也想支持`?`,你可以检查`query`是否设置并将其添加到最终结果中。 (2认同)

Mik*_*nko 15

对于那些喜欢我的人试图使用urlparse来提取密钥和存储桶以便用boto3创建对象.有一个重要的细节:从键的开头删除斜杠

from urlparse import urlparse
o = urlparse('s3://bucket_name/folder1/folder2/file1.json')
bucket = o.netloc
key = o.path
boto3.client('s3')
client.put_object(Body='test', Bucket=bucket, Key=key.lstrip('/'))
Run Code Online (Sandbox Code Playgroud)

花了一段时间才意识到因为boto3没有抛出任何异常.


hum*_*ume 11

最近的一个选择是使用cloudpathlib,它实现了pathlib云服务(包括 S3、Google Cloud Storage 和 Azure Blob Storage)上的文件的功能。

除了这些功能之外,还可以轻松获取 S3 路径的存储桶和密钥。

from cloudpathlib import S3Path

path = S3Path("s3://bucket_name/folder1/folder2/file1.json")

path.bucket
#> 'bucket_name'

path.key
#> 'folder1/folder2/file1.json'
Run Code Online (Sandbox Code Playgroud)


小智 9

一个没有urllib或re的解决方案(也可以处理前面的斜杠):

def split_s3_path(s3_path):
    path_parts=s3_path.replace("s3://","").split("/")
    bucket=path_parts.pop(0)
    key="/".join(path_parts)
    return bucket, key
Run Code Online (Sandbox Code Playgroud)

跑步:

bucket, key = split_s3_path("s3://my-bucket/some_folder/another_folder/my_file.txt")
Run Code Online (Sandbox Code Playgroud)

返回值:

bucket: my-bucket
key: some_folder/another_folder/my_file.txt
Run Code Online (Sandbox Code Playgroud)

  • 可能更好使用 [`.partition("/")`](https://docs.python.org/3/library/stdtypes.html#str.partition) 而不是 `.split("/")` 和`.join("/")`。`bucket, _, key = s3_path.replace("s3://","").partition("/")` 另外,这是假设 `s3://` 没有作为子字符串出现在路径中本身。任何理智的人都不会这样做,但也许攻击者可以利用这一点?没有把握。 (6认同)

Gra*_*eth 9

使用一行内置的字符串方法很容易完成......

s3_filepath = "s3://bucket-name/and/some/key.txt"
bucket, key = s3_filepath.replace("s3://", "").split("/", 1)
Run Code Online (Sandbox Code Playgroud)


Lio*_*ahi 7

这是一个不错的项目:

s3path是 aws s3 服务的 pathlib 扩展

>>> from s3path import S3Path
>>> path = S3Path.from_uri('s3://bucket_name/folder1/folder2/file1.json')
>>> print(path.bucket)
'/bucket_name'
>>> print(path.key)
'folder1/folder2/file1.json'
>>> print(list(path.key.parents))
[S3Path('folder1/folder2'), S3Path('folder1'), S3Path('.')]
Run Code Online (Sandbox Code Playgroud)


Ale*_*itt 6

如果要使用正则表达式执行此操作,则可以执行以下操作:

>>> import re
>>> uri = 's3://my-bucket/my-folder/my-object.png'
>>> match = re.match(r's3:\/\/(.+?)\/(.+)', uri)
>>> match.group(1)
'my-bucket'
>>> match.group(2)
'my-folder/my-object.png'
Run Code Online (Sandbox Code Playgroud)

这样的好处是您可以检查该s3方案,而不是在其中允许任何操作。


小智 6

这可以顺利完成

bucket_name, key = s3_uri[5:].split('/', 1)
Run Code Online (Sandbox Code Playgroud)