如何使用Boto3和AWS资源从S3中下载对象?
问题描述 − 使用Python中的boto3库在给定的本地路径/默认路径上下载S3中的对象,并覆盖现有文件。例如,从S3的Bucket_1/testfolder下载test.zip。
更多Python相关文章,请阅读:Python 教程
解决该问题的方法/算法
步骤1 − 导入boto3和botocore exceptions以处理异常。
步骤2 − 从 pathlib 导入Path以检查文件名。
步骤3 − s3_path,localpath 和 overwrite_existing_file 是函数 download_object_from_s3 的三个参数。
步骤4 − 验证 s3_path 是否以AWS格式 s3://bucket_name/key 传递。默认情况下, localpath = None 和 overwrite_existing_file = True 。用户也可以传递这些值以在给定的本地路径中下载。
步骤5 − 使用boto3库创建AWS会话。
步骤6 − 为S3创建AWS资源。
步骤7 − 拆分S3路径并执行操作以分离根Bucket名称和要下载的对象路径。
步骤8 − 检查是否将 overwrite_existing_file 设置为False且文件已经存在于给定的本地路径中;在这种情况下不进行任何操作。
步骤9 − 否则(如果这些条件中有任何一个条件不成立),则下载该对象。如果给定了localpath,则下载到该位置;否则下载到默认路径中。
步骤10 − 根据响应代码处理异常以验证文件是否已下载。
步骤11 − 如果下载文件时出现问题,则处理通用异常。
例子
使用以下代码从AWS S3中下载文件-
import boto3
from botocore.exceptions import ClientError
from pathlib import Path
def download_object_from_s3(s3path, localPath=None,
overwrite_existing_file=True):
if 's3://' not in s3path:
print('给定的路径不是有效的S3路径.')
raise Exception('给定的路径不是有效的S3路径.')
session = boto3.session.Session()
s3_resource = session.resource('s3')
s3_tokens = s3path.split('/')
bucket_name = s3_tokens[2]
object_path = ""
filename = s3_tokens[len(s3_tokens) - 1]
print('文件名:'+filename)
if len(s3_tokens) > 4:
for tokn in range(3, len(s3_tokens) - 1):
object_path += s3_tokens[tokn] + "/"
object_path += filename
else:
object_path += filename
print('对象:'+object_path)
try:
if not overwrite_existing_file and Path.is_file(filename):
pass
else:
if localPath is None:
s3_resource.meta.client.download_file(bucket_name, object_path, filename)
else:
s3_resource.meta.client.download_file(bucket_name, object_path, localPath + '/' + filename)
print('文件名:'+filename)
return filename
except ClientError as error:
if error.response['Error']['Code'] == '404':
print(s3path + " 文件未找到: ")
raise Exception(s3path + " 文件未找到: ")
except Exception as error:
print("S3助手中的download_object函数出现意外错误: " + error.__str__())
raise Exception("S3助手中的download_object函数出现意外错误: " + error.__str__())
#下载到默认本地路径
print(download_object_from_s3("s3://Bucket_1/testfolder/test.zip"))
#下载到给定路径
print(download_object_from_s3("s3://Bucket_1/testfolder/test.zip","C://AWS"))
#文件在S3上不存在
print(download_object_from_s3("s3://Bucket_1/testfolder/abc.zip"))
输出
#下载到默认本地路径
文件名:test.zip
对象:testfolder/test.zip
文件名:test.zip
#下载到给定路径
文件名:test.zip
对象:testfolder/test.zip
文件名:test.zip
#文件在S3上不存在
文件名:abc.zip
对象:testfolder/abc.zip
s3://Bucket_1/testfolder/abc.zip 文件未找到:
botocore.exceptions.ClientError: 在调用HeadObject操作时发生错误(404):未找到
注意: 默认下载路径是编写此函数的目录。如果未提供本地路径,则文件将下载到该目录中。 例如,如果此函数写入S3_class中,并且该类位于C://AWS/src/S3_class中,则文件test.zip将下载到C://AWS/src/test.zip中。
极客教程