我使用以下代码从存储在 .json 文件中的网络抓取字符串中解析以逗号分隔的 JSON 多行对象:
import json
def stream_read_json(fn):
start_pos = 0
with open(fn, 'r', encoding='utf-8') as f:
while True:
try:
obj = json.load(f)
yield obj
return
except json.JSONDecodeError as e:
f.seek(start_pos)
json_str = f.read(e.pos)
obj = json.loads(json_str, encoding = 'utf-8')
start_pos += e.pos
yield obj
第一个对象解析正确;接下来的不是。 在测试
f.seek(start_pos)
的随机值时,我发现与 except json.JSONDecodeError as e:
找到的索引不一致。为什么此索引与我在 IDE 上选择文本直到文件中 JSON 对象结束的字符时显示的字符数不同?
如何确保对象被正确解析?
我尝试在调试提示符处获取第二个 JSON 对象的
f.seek(start_pos)
,但它与错误抛出的 e.pos
有很大不同。
JSON 示例如下:
{
"user": {
"id": 1,
"profile": {
"name": "Alice",
"age": 30
}
},
"product": {
"sku": "A1234",
"details": {
"name": "Laptop",
"price": 999.99
}
}
},
{
"user": {
"id": 2,
"profile": {
"name": "Bob",
"age": 22
}
},
"product": {
"sku": "A123w",
"details": {
"name": "Laptop",
"price": 9.99
}
}
}
这绝对不是正确的方法,应该如何完成,但我会针对您的特定情况建议一种解决方法。
问题是你的“json”并不是真正的json,因为缺少括号
[]
和很多重复的键。但作为解决方法,您可以执行以下操作:
import json
with open("test.json", "r") as file:
str_data: str = file.read()
dict_data: dict = json.loads(f"[{str_data}]")
是的,可以这样做,但我不推荐这样做。
您的问题是:
encoding=
添加到 json.loads()
我测试过这段代码:
def stream_read_json(fn):
start_pos = 0
with open(fn, 'r', encoding='utf-8') as f:
while True:
try:
obj = json.load(f)
yield obj
return
except json.JSONDecodeError as e:
f.seek(start_pos)
json_str = f.read(e.pos)
obj = json.loads(json_str)
yield obj
f.read(1)
start_pos += e.pos + 1