我需要解析其他工具生成的文件,该工具无条件地输出带有 UTF-8 BOM 标头(EFBBBF)的 json 文件。我很快发现这是问题所在,因为 Python 2.7 模块似乎无法解析它:
>>> import json
>>> data = json.load(open('sample.json'))
ValueError: No JSON object could be decoded
删除BOM,解决了,但我想知道是否有另一种解析带有BOM头的json文件的方法?
您可以打开codecs
:
import json
import codecs
json.load(codecs.open('sample.json', 'r', 'utf-8-sig'))
或自己解码utf-8-sig
并传递给loads
:
json.loads(open('sample.json').read().decode('utf-8-sig'))
简单的!您甚至不需要导入codecs
.
with open('sample.json', encoding='utf-8-sig') as f:
data = json.load(f)
由于在引擎盖下json.load(stream)
使用json.loads(stream.read())
,编写一个 lstrips BOM 的小 hepler 函数不会那么糟糕:
from codecs import BOM_UTF8
def lstrip_bom(str_, bom=BOM_UTF8):
if str_.startswith(bom):
return str_[len(bom):]
else:
return str_
json.loads(lstrip_bom(open('sample.json').read()))
在其他需要包装流并以某种方式修复它的情况下,您可能会考虑从codecs.StreamReader
.
您也可以使用关键字with
import codecs
with codecs.open('samples.json', 'r', 'utf-8-sig') as json_file:
data = json.load(json_file)
或更好:
import io
with io.open('samples.json', 'r', encoding='utf-8-sig') as json_file:
data = json.load(json_file)
如果这是一次性的、非常简单的、对我有用的超高科技解决方案……
BOOM,BOM 标头不见了!
我使用 Linux 命令手动删除了 BOM。
首先,我检查文件是否有efbb bf
字节,使用head i_have_BOM | xxd
.
然后我跑dd bs=1 skip=3 if=i_have_BOM.json of=I_dont_have_BOM.json
。
bs=1
每次处理 1 个字节skip=3
,跳过前 3 个字节。
我只使用 utf-8-sig 和 import json
with open('estados.json', encoding='utf-8-sig') as json_file:
data = json.load(json_file)
print(data)