如何用boto3下载S3文件夹内文件?Lambda报错求助
S3子文件夹文件下载问题解决及批量遍历方案
一、解决当前NoSuchKey错误
你指定的S3对象key开头多了斜杠/,S3的对象key不能以斜杠开头——S3没有真实的文件夹结构,所谓“文件夹”只是对象key里的前缀分隔符,修正key格式即可正常下载。
修正后的代码:
import boto3 s3_client = boto3.client("s3") # 去掉key开头的斜杠 s3_client.download_file( 'sumanth-bsig-test', 'big_data1/2022.02.11_at_22.03.11_radar-mi_5354_sec_4989385772_5092940872.bsig', '/tmp/SampleFile.bsig' )
二、批量遍历所有子文件夹下载特定文件
以下代码可遍历S3桶内所有子文件夹,自动筛选并下载指定后缀(比如.bsig)的文件到Lambda的/tmp目录,同时处理同名文件避免覆盖:
import boto3 import os s3_client = boto3.client("s3") bucket_name = 'sumanth-bsig-test' # 可修改为你需要的特定文件后缀或文件名规则 target_file_suffix = '.bsig' tmp_storage_path = '/tmp' # 分页遍历S3桶内所有对象(避免大桶单次返回数据过多) paginator = s3_client.get_paginator('list_objects_v2') for page in paginator.paginate(Bucket=bucket_name): if 'Contents' not in page: continue for obj in page['Contents']: obj_key = obj['Key'] # 跳过S3中的空文件夹对象(key以/结尾) if obj_key.endswith('/'): continue # 筛选符合条件的文件 if obj_key.endswith(target_file_suffix): # 生成本地存储路径,处理同名文件 base_filename = os.path.basename(obj_key) local_file_path = os.path.join(tmp_storage_path, base_filename) # 如果文件已存在,添加序号后缀 count = 1 while os.path.exists(local_file_path): name_part, ext_part = os.path.splitext(base_filename) local_file_path = os.path.join(tmp_storage_path, f"{name_part}_{count}{ext_part}") count += 1 # 执行下载 s3_client.download_file(bucket_name, obj_key, local_file_path)
注意事项
- Lambda的
/tmp是临时存储,函数执行完毕后会被清空,若需持久化文件,需下载后上传至其他持久化存储服务 - 确保Lambda的执行角色拥有
s3:ListBucket(遍历桶权限)和s3:GetObject(下载文件权限) - 若桶内文件数量极大,需注意Lambda的15分钟执行时间限制,可考虑用S3事件触发分批处理
内容的提问来源于stack exchange,提问作者sumanth shetty
相关产品推荐
相关产品推荐

