python - 解析 json 给出 JSONDecodeError: Unterminated string
问题描述
我有一个带有换行符分隔 json 的文档,我在其中应用了一些功能。一切正常,直到这条线,它看起来完全像这样:
{"_id": "5f114", "type": ["Type1", "Type2"], "company": ["5e84734"], "answers": [{"title": " answer 1", "value": false}, {"title": "answer 2
", "value": true}, {"title": "This is a title.", "value": true}, {"title": "This is another title", "value": true}], "audios": [null], "text": {}, "lastUpdate": "2020-07-17T06:24:50.562Z", "title": "This is a question?", "description": "1000 €.", "image": "image.jpg", "__v": 0}
整个代码:
import json
def unimportant_function(d):
d.pop('audios', None)
return {k:v for k,v in d.items() if v != {}}
def parse_ndjson(data):
return [json.loads(l) for l in data.splitlines()]
with open('C:\\path\\the_above_example.json', 'r', encoding="utf8") as handle:
data = handle.read()
dicts = parse_ndjson(data)
for d in dicts:
new_d = unimportant_function(d)
json_string=json.dumps(new_d, ensure_ascii=False)
print(json_string)
错误JSONDecodeError: Unterminated string starting at: line 1 column 260 (char 259)
发生在dicts = parse_ndjson(data)
。为什么?我也不知道“答案 2”之后的那个符号是什么,它没有出现在数据中,但是当我复制粘贴它时它出现了。
数据有什么问题?
解决方案
嵌入在"answer 2"
字符串中的不可打印字符是段落分隔符,它被视为空格.splitlines()
:
>>> 'foo\u2029bar'.splitlines()
['foo', 'bar']
(推测:ndjson 文件可能正在利用它来表示“这个字符串应该有一个换行符”,围绕文件格式工作。如果是这样,它可能应该使用\n
转义符。)
但是,如果您正常遍历文件的行,则不会对字符进行特殊处理:
>>> # For demonstration purposes, I create a `StringIO`
>>> # from a hard-coded string. A file object reading
>>> # from disk will behave similarly.
>>> import io
>>> for line in io.StringIO('foo\u2029bar'):
... print(repr(line))
...
'foo\u2029bar'
因此,简单的解决方法是让parse_ndjson
期望的行序列已经 - 不要调用.splitlines
,并适当地修复调用代码。您可以handle
直接通过 open :
def parse_ndjson(data):
return [json.loads(l) for l in data]
with open('C:\\path\\the_above_example.json', 'r', encoding="utf8") as handle:
dicts = parse_ndjson(handle)
或将其传递list
给以显式创建列表:
def parse_ndjson(data):
return [json.loads(l) for l in data]
with open('C:\\path\\the_above_example.json', 'r', encoding="utf8") as handle:
dicts = parse_ndjson(list(handle))
.readlines()
或使用提供的方法创建列表:
def parse_ndjson(data):
return [json.loads(l) for l in data]
with open('C:\\path\\the_above_example.json', 'r', encoding="utf8") as handle:
dicts = parse_ndjson(handle.readlines())
推荐阅读
- java - 如何在迭代和检查对象的另一个 ArrayList 时将实体值更新为 ArrayList 中的对象
- arrays - 我正在运行 opencv 代码并收到此错误 ValueError: The truth value of an array with more than one element is ambiguous。使用 a.any() 或 a.all()
- c# - 如何使用 GraphicsPath 绘制形状以创建自定义控件的区域?
- assembly - 我应该如何在程序集 8086 中命名我的标签
- python - 如何通过 ManyToManyField 检索 django 模板中的 .count
- reactjs - React Native 在 https 请求上从 REST api 获取数据错误
- c# - 使用 InMemoryDatabase 返回计数为 0 的 NUnit 测试
- angular - 如何使用 Angular 路由器模块在 Ionic 5 中显示选项卡
- android - 分支 IO 深层链接自定义别名不起作用。相同的链接不在两个不同的应用程序中共享?
- zfs - 物理端口移动后 ZFS 路径不匹配