使用boto3遍历S3文件夹报'NoneType' object is not iterable错误如何解决
问题排查与修复方案
报错根因
TypeError: 'NoneType' object is not iterable 报错的核心原因是:当你指定的S3前缀路径下没有任何子前缀时,list_objects接口的返回结果不会包含CommonPrefixes字段,调用.get('CommonPrefixes')会返回None,直接对None执行for循环遍历就会触发该错误。
你的场景中触发报错的可能原因:
- 拼接的路径
region+year+'/'+month+'/'+day+'/'下不存在对应子目录,比如对应日期该区域没有CloudTrail日志生成、路径拼写错误 - 哪怕替换为
2021/作为前缀,只要该前缀下没有子目录,同样会触发相同报错
修复建议
- 每次获取
CommonPrefixes后先做非空校验,确认有返回值再遍历 - 不要重复定义同名变量,避免逻辑混乱(比如你的代码中同时用
region存接口返回结果和子前缀值,files也存在同名复用的问题) - 建议使用
list_objects_v2替代已过时的list_objects接口,同时适配分页逻辑,避免前缀超过1000个时出现数据遗漏
修复后参考代码
from datetime import datetime now = datetime.now() year = now.strftime("%Y") month = now.strftime("%m") day = now.strftime("%d") # 第一层:取AWSLogs下的账号前缀 account_resp = bucket.meta.client.list_objects_v2(Bucket=bucket.name, Prefix='AWSLogs/', Delimiter='/') account_prefixes = account_resp.get('CommonPrefixes', []) for account in account_prefixes: list_account = account.get('Prefix') # 第二层:取对应账号下的CloudTrail区域前缀 region_resp = bucket.meta.client.list_objects_v2(Bucket=bucket.name, Prefix=f"{list_account}CloudTrail/", Delimiter='/') region_prefixes = region_resp.get('CommonPrefixes', []) for region_item in region_prefixes: region = region_item.get('Prefix') # 第三层:取对应年月日下的前缀 target_prefix = f"{region}{year}/{month}/{day}/" file_resp = bucket.meta.client.list_objects_v2(Bucket=bucket.name, Prefix=target_prefix, Delimiter='/') file_prefixes = file_resp.get('CommonPrefixes', []) for file_item in file_prefixes: print(file_item.get('Prefix'))
上述代码用
.get('CommonPrefixes', [])在无对应字段时默认返回空列表,避免遍历None的报错,同时拆分了同名变量,替换为更规范的v2接口。
内容的提问来源于stack exchange,提问作者ParkSoy
相关产品推荐
相关产品推荐

