如何在单个文件中正确保存多个GitHub API返回的JSON对象?
解决GitHub Commit JSON数据存储的问题
我来帮你搞定这个问题!你碰到的KeyError: extra data其实是个典型的JSON格式问题——你直接把多个独立的JSON对象追加写入文件,这根本不符合JSON的语法规则,解析器当然读不懂啦。
JSON规范要求单个文件里只能有一个顶级元素:要么是单个JSON对象,要么是一个包含多个对象的数组。直接追加的话,文件内容会变成{...}{...}这种“多个顶级对象”的形式,解析器读到第一个对象结束的}后,发现后面还有多余内容,就会抛出错误。
下面给你两个实用的解决方案,按需选择:
方案1:用数组包裹所有Commit数据(标准JSON格式)
这是最通用的做法,适合数据量不大的场景,读取和处理都很方便:
- 先初始化一个空列表,用来存所有commit的JSON数据
- 遍历每个commit链接,把获取到的JSON对象添加到列表里
- 最后一次性把整个列表写入文件
举个Python的实现例子:
import json import requests # 初始化存储所有commit数据的列表 commits_list = [] # 假设这是你收集到的commit链接列表 commit_links = ["commit_link1", "commit_link2"] for link in commit_links: # 请求commit数据并转成JSON对象 resp = requests.get(link) commit_data = resp.json() commits_list.append(commit_data) # 将整个列表写入JSON文件,indent=4让格式更易读 with open("all_commits.json", "w", encoding="utf-8") as f: json.dump(commits_list, f, indent=4, ensure_ascii=False)
读取的时候直接加载整个数组就行:
with open("all_commits.json", "r", encoding="utf-8") as f: all_commits = json.load(f) # 遍历处理每个commit for commit in all_commits: print(f"Commit SHA: {commit['sha']}")
方案2:使用JSON Lines格式(适合大数据量)
如果你的commit数量特别多,一次性把所有数据加载到内存可能会有压力,那JSON Lines(.jsonl后缀)是更好的选择——每行存储一个独立的JSON对象,既符合规范,又能逐行读取,节省内存。
写入方式:
import json import requests commit_links = ["commit_link1", "commit_link2"] with open("all_commits.jsonl", "w", encoding="utf-8") as f: for link in commit_links: resp = requests.get(link) commit_data = resp.json() # 把单个JSON对象转成字符串,加换行后写入 f.write(json.dumps(commit_data, ensure_ascii=False) + "\n")
读取方式(逐行解析,内存友好):
with open("all_commits.jsonl", "r", encoding="utf-8") as f: for line in f: # 跳过空行,解析单行JSON if line.strip(): commit = json.loads(line) print(f"Commit SHA: {commit['sha']}")
为什么之前的追加模式不行?
你之前用追加模式写出来的文件内容大概是这样的:
{"sha": "abc123", "message": "fix bug"} {"sha": "def456", "message": "add feature"}
这不是有效的JSON,因为JSON不允许多个顶级对象并存。解析器处理完第一个}后,发现后面还有内容,就会抛出“extra data”的错误。
内容的提问来源于stack exchange,提问作者mishi ahmad
相关产品推荐
相关产品推荐

