使用boto3从Amazon S3下载文件夹部分文件报404错误求助
针对S3批量下载仅部分文件成功的问题分析与解决
首先,咱们把这个404错误的本质说透:当你用boto3的download_file方法时,它会先调用S3的HeadObject接口确认文件存在性并获取元数据,这个报错直接说明那些失败的文件在S3的/test/files/路径下压根不存在。而A5、A6能正常下载,就证明这两个文件确实在目标位置,问题出在其他文件的存在性或者你的代码/路径配置上。
接下来一步步解决:
1. 先确认S3上的文件真实状态
别着急查代码,先去AWS控制台的S3页面,找到对应的存储桶,导航到test/files/目录,逐个检查A1-A4、A7-A25.tmp这些文件是不是真的在这儿。常见的坑有:
- 文件名大小写问题:S3对象键区分大小写,比如实际上传的是
a1.tmp,但你代码里写的是A1.tmp - 路径错误:文件可能被传到了
test/或者files/根目录,而非test/files/下面 - 文件已被删除:这些文件可能之前存在,但后来被手动删除或通过生命周期规则清理了
嫌控制台操作麻烦的话,用AWS CLI跑个命令就能快速列出所有文件:
aws s3 ls s3://你的存储桶名称/test/files/ --recursive
把输出的文件名和你要下载的列表对比,一眼就能看出哪些文件缺失。
2. 检查代码里的文件名和路径逻辑
看看你的download_contents_s3函数,重点确认:
- 循环生成文件名的逻辑有没有问题:比如循环范围写错了?或者拼接文件名时格式出错(多打了符号、少了数字)
- S3对象键的拼接是否正确:比如
test/files/后面是不是多了斜杠?如果你的s3_prefix已经包含末尾斜杠,再拼接文件名就会变成test/files//A1.tmp,这也会导致找不到文件
3. 给代码加错误处理,避免批量任务中断
如果确实有部分文件不存在(比如业务场景允许这种情况),那最好在代码里捕获404错误,跳过不存在的文件,继续下载其他文件,示例代码如下:
import boto3 from botocore.exceptions import ClientError def download_contents_s3(self, bucket_name, s3_prefix, local_dir): s3_client = boto3.client('s3') # 循环生成要下载的文件名 for file_num in range(1, 26): s3_file_name = f"A{file_num}.tmp" # 用rstrip('/')避免出现双斜杠的情况 s3_object_key = f"{s3_prefix.rstrip('/')}/{s3_file_name}" local_file_path = f"{local_dir}/{s3_file_name}" try: s3_client.download_file(bucket_name, s3_object_key, local_file_path) print(f"✅ 成功下载: {s3_file_name}") except ClientError as err: error_code = err.response['Error']['Code'] if error_code == '404': print(f"⚠️ 文件不存在,跳过: {s3_object_key}") else: # 其他错误(比如权限问题)直接抛出,不吞掉异常 raise err
4. 排除权限问题(概率低,但可以确认)
因为有两个文件能成功下载,所以你的IAM账号肯定有s3:GetObject和s3:HeadObject权限。不过如果某些文件设置了特殊ACL(比如私有且未给你的账号授权),S3会用404隐藏权限不足的真实错误。如果前面的步骤都没问题,可以检查一下这些失败文件的ACL设置,确认你的账号能访问它们。
内容的提问来源于stack exchange,提问作者Sruthi
相关产品推荐
相关产品推荐

