Python使用UTF-8 BOM头加载json文件

the*_*eta 35 python json

我需要解析由其他工具生成的文件,这些工具无条件地输出带有UTF-8 BOM头(EFBBBF)的json文件.我很快发现这是问题,因为Python 2.7模块似乎无法解析它:

>>> import json
>>> data = json.load(open('sample.json'))

ValueError: No JSON object could be decoded
Run Code Online (Sandbox Code Playgroud)

删除BOM,解决它,但我想知道是否有另一种方法解析带有BOM头的json文件?

Pav*_*sov 64

你可以打开codecs:

import json
import codecs

json.load(codecs.open('sample.json', 'r', 'utf-8-sig'))
Run Code Online (Sandbox Code Playgroud)

或者utf-8-sig自己解码并传递给loads:

json.loads(open('sample.json').read().decode('utf-8-sig'))
Run Code Online (Sandbox Code Playgroud)

  • 我强烈建议使用`io.open()`而不是`codecs.open()`:`json.load(io.open('sample.json','r',encoding ='utf-8-sig')) `.`io`模块更强大,更快. (16认同)

Aer*_*rin 21

简单的!您甚至不需要导入codecs.

with open('sample.json', encoding='utf-8-sig') as f:
    data = json.load(f)
Run Code Online (Sandbox Code Playgroud)


new*_*ver 5

因为在引擎盖下json.load(stream)使用json.loads(stream.read()),所以编写一个小的管理BOM的小函数也不会那么糟糕:

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()))    
Run Code Online (Sandbox Code Playgroud)

在其他情况下,您需要包装流并以某种方式修复它,您可能会看到继承codecs.StreamReader.

  • @SamStoelinga,因为strip函数不接收前缀而是接收要删除的一组字符.你需要将字节串解码为`unicode`或使用上面的方法确保你只删除UTF-8 BOM. (3认同)