如何批量解压DataFrame列中的json.gz文件并解决OSError报错
报错原因
- 列内存储的文件名前后自带多余单引号:从给出的样例能看到,location列的实际值是
'0_location_data.json.gz',字符串首尾的单引号是内容的一部分,不是文件名的合法组成,传给gzip.open时会被识别成无效路径,直接触发OSError: [Errno 22]。 - 代码存在笔误:原代码中
list(df['location])的字符串引号未闭合,运行时会先触发语法错误。 - 存在资源泄漏风险:原写法用生成器链式读取文件流,没有显式关闭文件句柄,批量处理数千个文件时很容易触发系统文件句柄数上限的报错。
- 缺失核心处理逻辑:原代码仅逐行打印解压后的文本,没有做JSON解析、结构规范化、导出CSV的步骤,也没有处理文件路径拼接问题——如果json.gz文件和脚本运行目录不一致,即使文件名正确也会报找不到文件。
正确实现方案
处理逻辑:先清洗文件名、补全文件完整路径,再逐个用上下文管理器打开gzip文件(自动释放资源),解析JSON后做结构化展平,最后合并所有数据导出CSV,同时加了异常捕获避免单个文件损坏中断整个任务。
import pandas as pd import gzip import json import os from pandas import json_normalize # -------------------------- 配置项 按需修改 -------------------------- # 存储文件名列表的元数据CSV路径 meta_csv_path = "你的文件元数据csv路径.csv" # json.gz文件实际存放的文件夹路径,和脚本同目录就填"./" gz_file_root = "./json_gz_store_folder/" # 最终规范化后导出的CSV路径 output_csv_path = "final_structured_data.csv" # ------------------------------------------------------------------- # 1. 读入元数据,清洗文件名字段 df = pd.read_csv(meta_csv_path) # 去掉location字段首尾的空白字符、多余单引号 df["clean_filename"] = df["location"].str.strip().str.strip("'") # 拼接得到文件的完整访问路径 df["full_file_path"] = df["clean_filename"].apply(lambda x: os.path.join(gz_file_root, x)) all_parsed_data = [] # 2. 遍历处理每个压缩包 for file_path in df["full_file_path"]: try: # with上下文管理器会自动关闭文件,避免句柄泄漏 with gzip.open(file_path, 'rt', encoding='utf-8') as f: # 两种常见JSON存储格式二选一,按需启用 # --- 场景A:单个gz包内是一整个完整的JSON对象/数组 --- json_content = json.load(f) normalized_chunk = json_normalize(json_content) all_parsed_data.append(normalized_chunk) # --- 场景B:gz包是JSON Lines格式(每行一个独立JSON,多数批量导出场景用这个) # 把上面场景A的三行注释掉,放开下面的代码 # for line in f: # line = line.strip() # if not line: # continue # json_obj = json.loads(line) # normalized_chunk = json_normalize(json_obj) # all_parsed_data.append(normalized_chunk) print(f"处理完成: {file_path}") except Exception as e: print(f"跳过异常文件 {file_path},错误信息: {str(e)}") continue # 3. 合并所有数据导出为CSV if all_parsed_data: final_df = pd.concat(all_parsed_data, ignore_index=True) # 用utf-8-sig编码导出,Windows下Excel打开不会乱码 final_df.to_csv(output_csv_path, index=False, encoding='utf-8-sig') print(f"全部任务完成,共导出{len(final_df)}条数据到{output_csv_path}") else: print("未解析到任何有效数据")
使用提示:如果解压时遇到编码报错,把
gzip.open里的encoding参数改成文件实际编码即可,比如gbk。如果JSON有多层嵌套结构,可以给json_normalize传入record_path、meta参数,自定义要展开的嵌套字段路径。
内容的提问来源于stack exchange,提问作者Zane
相关产品推荐
相关产品推荐

