【编程之路】Python 解压 zip 文件 & 读取 json 文件

本文详细介绍了如何使用Python解压缩zip文件中的json文件,并展示了查看压缩内容、解压操作的方法,以及逐行读取和pandas读取json的技巧,还包括了遇到错误的解决方案。

Python 解压 zip 文件 & 读取 json 文件

参加了一个比赛,提供的数据集只能在它的平台使用且无法下载,文件为 zip 格式,经查看里面包含了 csv 格式的文件和 json 格式的文件。

1.查看压缩包内文件

# 查看压缩包内所有文件
with zipfile.ZipFile('xxx.zip','r') as zipobj:
	for filename in zipobj.namelist():
		print(filename.encode('cp437').decode('utf-8'))

2.解压操作

# 解压某个文件
f = zipfile.ZipFile('xxx.zip', 'r')
f.extract('xxx.json', path='xxx', pwd=None)
# 解压全部文件
f = zipfile.ZipFile('xxx.zip', 'r')
for file in f.namelist():
    f.extract(file, path='xxx')       

或者(在 Jupyter Notebook 环境中)

# 解压到当前目录
!unzip xxx.zip

# 解压到指定目录下
!unzip -d 路径 xxx.zip

# 查看zip内容,但不解压
!unzip -l xxx.zip

3.读取 json 文件

# 读取第一行
with open("xxx.json", "r+") as f:
    data = f.readline()
data

读取 json 文件出错的解决方法

# 由于文件中有多行,直接读取会出现错误,因此一行一行读取
file = open("xxx.json", 'r', encoding='utf-8')
papers = []
for line in file.readlines():
    dic = json.loads(line)
    papers.append(dic)
    
print(papers)

当然可以利用 pandas 自带的 read_json

df = pd.read_json("xxx.json", encoding="utf-8", orient='records', lines=True) # 按行读取
df.head()
<think>嗯,用户的问题是关于如何用Python读取zip文件中的特定JSON文件,并提取指定的键值对到数组中。我需要一步步思考怎么解决这个问题。 首先,我需要确认用户的需求。用户有一个zip文件,里面可能有多个文件,但用户只关心其中的某个JSON文件。然后,需要从这个JSON文件读取特定的键值对,并将这些键值对存储到一个数组(列表)中。可能需要考虑JSON文件的结构,比如是对象还是数组,以及如何处理嵌套的情况。 接下来,我需要回忆Python处理zip文件的标准库。Pythonzipfile模块应该可以处理zip文件。使用ZipFile打开zip文件,然后找到目标JSON文件读取其内容。然后,用json模块解析JSON数据。 然后,考虑如何提取特定的键值对。假设用户知道要提取哪些键,例如,键为"name"和"age"的值。需要遍历JSON数据结构,提取这些键对应的值。如果JSON结构比较复杂,可能需要递归或者特定的路径来访问嵌套的键。 可能的步骤是: 1. 使用zipfile.ZipFile打开zip文件。 2. 找到目标JSON文件文件名,可能需要遍历文件列表。 3. 读取文件的内容,转换为字符串。 4. 用json.loads解析成Python对象(字典或列表)。 5. 根据键名提取对应的值,可能需要递归查找。 6. 将提取的键值对添加到数组中。 需要注意的是,如果JSON文件很大,直接读取可能会占用内存,但用户的问题可能假设文件大小适中。另外,异常处理也很重要,比如文件不存在、非JSON文件、键不存在等情况。 然后,代码示例的结构应该是怎样的?可能需要先导入必要的模块,如zipfile和json。然后打开zip文件,检查是否存在所需的JSON文件读取内容,解析,提取数据。最后将结果保存到列表中。 例如: ```python import zipfile import json def extract_from_zip(zip_path, target_file, keys): result = [] with zipfile.ZipFile(zip_path, 'r') as z: if target_file not in z.namelist(): raise FileNotFoundError(f"{target_file} not found in zip") with z.open(target_file) as f: data = json.load(f) # 提取逻辑 for key in keys: if key in data: result.append({key: data[key]}) return result ``` 不过,如果JSON结构是嵌套的,可能需要更复杂的提取方法,比如使用递归函数来遍历所有可能的键。或者,用户可能希望提取所有出现的某个键,不管层级如何。这部分需要明确用户的需求,但根据问题描述,用户可能只需要顶层的键值对。 另外,用户可能需要将结果存储为字典列表,或者是键值对的列表,比如每个元素是包含键和值的字典。例如,提取多个键,每个键对应一个字典项。 此外,可能需要考虑编码问题,确保读取文件时使用正确的编码格式,比如UTF-8。 总结步骤: 1. 打开zip文件,定位JSON文件。 2. 读取并解析JSON内容。 3. 遍历指定的键,提取对应的值。 4. 处理可能的异常情况,如键不存在。 5. 返回结果数组。 然后,生成相关问题,比如如何处理嵌套的键,如何批量处理多个JSON文件,或者如何优化大文件的处理效率。这有助于用户进一步探索解决方案。</think>### Python读取ZIP中的JSON文件并提取键值对 #### 实现步骤 1. **导入必要库** ```python import zipfile import json from typing import List, Dict ``` 2. **核心处理函数** ```python def extract_keys_from_zip(zip_path: str, json_filename: str, target_keys: List[str]) -> List[Dict]: """ 从ZIP压缩包中提取指定JSON文件的键值对 :param zip_path: ZIP文件路径,如 'data.zip' :param json_filename: ZIP内目标JSON文件名,如 'data.json' :param target_keys: 需要提取的键列表,如 ['id', 'name'] :return: 包含键值对的字典列表 """ result = [] with zipfile.ZipFile(zip_path, 'r') as z: # 检查目标文件是否存在 if json_filename not in z.namelist(): raise ValueError(f"文件 {json_filename} 不存在于ZIP压缩包中") # 读取JSON文件内容 with z.open(json_filename) as f: json_data = json.load(f) # 提取指定键值对 extracted = {key: json_data[key] for key in target_keys if key in json_data} # 处理嵌套结构(可选扩展) # 如需处理嵌套键,可使用递归函数遍历JSON结构 # extracted = deep_search(json_data, target_keys) if extracted: result.append(extracted) return result ``` 3. **使用示例** ```python # 示例调用 output = extract_keys_from_zip( zip_path = 'data.zip', json_filename = 'user_data.json', target_keys = ['user_id', 'email', 'registration_date'] ) print(output) # 输出示例:[{'user_id': 123, 'email': 'test@example.com'}] ``` #### 关键功能扩展 - **嵌套键值提取**:如果JSON包含嵌套结构,可添加递归搜索函数 ```python def deep_search(data, keys: List[str], current_path=""): results = {} if isinstance(data, dict): for k, v in data.items(): new_path = f"{current_path}.{k}" if current_path else k if k in keys: results[new_path] = v results.update(deep_search(v, keys, new_path)) elif isinstance(data, list): for index, item in enumerate(data): results.update(deep_search(item, keys, f"{current_path}[{index}]")) return results ``` - **异常处理增强**:添加更详细的错误检测 ```python try: output = extract_keys_from_zip(...) except zipfile.BadZipFile: print("ZIP文件损坏") except json.JSONDecodeError: print("JSON解析失败") ``` #### 性能优化建议 1. **流式处理大文件**:使用`ijson`库处理大型JSON文件 2. **并行处理**:对ZIP内多个JSON文件使用多线程处理 3. **内存优化**:使用生成器逐步输出结果
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据与AI实验室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值