如何使用Python 3.10.5在嵌套zip压缩包中搜索指定字符串
嵌套ZIP压缩包指定字符串检索方案
原有代码仅遍历了最外层压缩包的直接条目,遇到内层嵌套ZIP时直接按普通文本读取,没有做递归解析,因此无法检索到深层文件内容。通过递归识别、内存解析内层ZIP的方式即可实现任意层级嵌套压缩包的检索需求,可直接运行的修复代码如下:
import io import zipfile # 基础配置 SEARCH_STRING = 'ERROR ' EXCLUDE_KEYWORD = 'Test' OUTER_ZIP_PATH = "C:\\Python testing\\Logs-node1.zip" RESULT_SAVE_PATH = "C:\\Python testing\\my file.txt" def search_in_zip(zf, nested_path_prefix=""): """ 递归遍历zip对象内所有文件,检索目标字符串 :param zf: 已加载的ZipFile对象 :param nested_path_prefix: 嵌套层级路径前缀,用于记录文件的完整位置 """ for zip_info in zf.infolist(): # 跳过目录、跳过包含排除关键词的文件 if zip_info.is_dir() or EXCLUDE_KEYWORD in zip_info.filename: continue full_file_path = f"{nested_path_prefix}/{zip_info.filename}" if nested_path_prefix else zip_info.filename # 当前条目为zip压缩包时,递归进入内层检索 if zip_info.filename.lower().endswith('.zip'): # 直接在内存中读取内层zip字节流,无需解压到本地磁盘 inner_zip_bytes = io.BytesIO(zf.read(zip_info)) with zipfile.ZipFile(inner_zip_bytes) as inner_zf: search_in_zip(inner_zf, nested_path_prefix=full_file_path) continue # 普通文本文件逐行匹配 with io.TextIOWrapper(zf.open(zip_info), encoding="utf-8", errors='ignore') as f: for line_no, line in enumerate(f, 1): if SEARCH_STRING.lower() in line.lower(): # 追加写入结果,避免覆盖之前的匹配记录 with open(RESULT_SAVE_PATH, "a", encoding="utf-8") as res_file: res_file.write(f"{full_file_path} : {line_no} : {line}") if __name__ == "__main__": # 检索前清空旧的结果文件 with open(RESULT_SAVE_PATH, "w", encoding="utf-8") as f: f.write("") # 加载最外层压缩包启动检索 with zipfile.ZipFile(OUTER_ZIP_PATH) as outer_zf: search_in_zip(outer_zf)
关键调整说明
- 递归解析嵌套ZIP:读取到
.zip后缀的条目时,直接将其二进制内容加载到内存生成ZipFile对象继续遍历,无需将内层压缩包解压到本地磁盘,支持任意深度的嵌套结构 - 完整路径记录:匹配到目标字符串时会输出从最外层到目标文件的完整嵌套路径,例如
some_directory/zip3.zip/File1,可直接定位内容位置 - 修复结果写入逻辑:原代码使用
w模式写入结果,每次匹配到新内容都会覆盖之前的记录,改为追加写入模式,检索启动前先清空旧结果文件,保证输出内容完整 - 异常规避:新增目录条目判断,跳过压缩包内的文件夹路径,避免尝试打开目录抛出IO错误
内容的提问来源于stack exchange,提问作者Pranav Shah
相关产品推荐
相关产品推荐

