问题描述
读取一个字符串test_str,字符串是一个嵌套的json串,且含有list类型数据,其中含有中文。我需要抽取其中的某些字段,存于一个新的文件。
>>>test_str='{"username":"tom","hobby":["足球","篮球","乒乓球"]}'
最开始使用json.loads(test_str)
>>>import json
>>>json.loads(test_str)
>>>{u'username': u'tom', u'hobby': [u'\u8db3\u7403', u'\u7bee\u7403', u'\u4e52\u4e53\u7403']}
得到结果,数据前面都加上了 u,中文也变成了'\u8db3\u7403'之类的。
很明显又碰到了python2中文编码的坑,于是网上搜索解决办法。
试了一些方法,都无效或者报错:
'ascii' codec can't encode character u'\u2019'
尝试过的无效解决方法1
在代码开头加:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
尝试过的无效解决方法2
['hobby'][0].decode('unicode-escape')
或者
['hobby'][0].decode('utf-8')
等等一些encode('gbk')之类的
尝试过的无效解决方法3
在代码开头加:
# -- coding: utf-8 --
解决方案
后来搜索发现,josn.loads会默认将数据load成Unicode对象
转换搜索方向,从这里发现两个可行方法:
解决方法1
使用PyYaml包,但是只能将最外层的数据编码格式转换正确,里层的还是unicode编码:
>>>aml.safe_load(test_str)
{'username': 'tom', 'hobby': [u'\u8db3\u7403', u'\u7bee\u7403', u'\u4e52\u4e53\u7403']}
解决方法2
使用如下代码彻底解决,,数据存储到文件里还是乱码,但是读出来可以中文显示:
>>>data = json_loads_byteified(r)
>>>data
{'username': 'tom', 'hobby': ['\xe8\xb6\xb3\xe7\x90\x83', '\xe7\xaf\xae\xe7\x90\x83', '\xe4\xb9\x92\xe4\xb9\x93\xe7\x90\x83']}
>>>print data['hobby'][0]
足球
import json
def json_load_byteified(file_handle):
return _byteify(
json.load(file_handle, object_hook=_byteify),
ignore_dicts=True
)
def json_loads_byteified(json_text):
return _byteify(
json.loads(json_text, object_hook=_byteify),
ignore_dicts=True
)
def _byteify(data, ignore_dicts = False):
# if this is a unicode string, return its string representation
if isinstance(data, unicode):
return data.encode('utf-8')
# if this is a list of values, return list of byteified values
if isinstance(data, list):
return [ _byteify(item, ignore_dicts=True) for item in data ]
# if this is a dictionary, return dictionary of byteified keys and values
# but only if we haven't already byteified it
if isinstance(data, dict) and not ignore_dicts:
return {
_byteify(key, ignore_dicts=True): _byteify(value, ignore_dicts=True)
for key, value in data.iteritems()
}
# if it's anything else, return it in its original form
return data