Python3.x在解析含中文的文本文件时的问题

python 2.6以后把simplejson纳入到标准库中,使得python可以原生支持json解析。这个确实是很方便,从文档上来看,python的json解析似乎是相当简单,并且具有不错的扩展性。json在python下解析简单,个人觉得还是因为json的语法和python的相差不多,基本上json的k-v式结构在python中也几乎是完全一样的写法(当然引号的写法json还是要严格一些)。因此大多时候在python中只需要两三行代码就能完成json的解析。出来的结果直接就是python中的字典类型数据。不过下面要说的是解析中碰到的几个比较烦人的小问题。


1. python 3以后,文件io方面似乎与以前有了很大的不同,最明显的一点就是有些时候使用字符串的形式读入文件的内容的时候会蹦出一些以前没有出现的错误,这些大多是文件编码的错误。比如今天我做实验,用豆瓣api文档中的 json示例代码 来做json解析的实验材料就碰到这种问题。
源代码是这样的:
with open('json_test.json') as json_file:
    raw_data = json_file.read()
    data = json.loads("".join(raw_data.split()))
print(data)
这段代码在python3.2中执行时会提示UnicodeDecodeError: 'gbk' codec can't decode bytes in position 104-105: illegal multibyte sequence
问题出在第二行代码中。而我的json文件是以utf-8的编码保存的。从错误提示中也可以发现,python会把这种编码的文件中的非英文字符当做字节来处理。因此唯一的办法是改变读取文件的模式,以字节的方式读入,然后讲读入的字节转换为字符串就可以了。

2. 但是这样又会有另一个问题。如果够细心的话会发现即便你将文件保存为utf-8编码,你的文件能够正确读入并正确转换为字符串。你依然会发现当程序运行到json.loads()的时候会蹦出一个很莫名其妙的ValueError: No JSON object could be decoded。而豆瓣上的示例代码并没有任何的错误,因此这是一个让人很沮丧的问题。网上有篇 博客 谈到了这个问题。原因跟utf-8的编码有关系的,python自带的json包不支持带bom的utf-8,因此,需要解析的json不可以以带bom的utf-8编码保存,只能是无BOM的。

3.此外还有个小问题:当json文档中含有非文本的空白字符,如换行符‘\n’等字符时,解析的时候会提示Invalid control character错误。对于这个问题有两种解决方案。一种是用replace方法将这些字符用空白字符或者空字符替换,另一种方法就是干脆利用split方法将字符串分开然后用“”.join方法连接起来。个人更喜欢第二种方法,因为豆瓣返回的json中会把用户输入的换行符等字符转义,这也是绝大多数应用对于数据的标准处理方法,而第二种方法可以将这种转义转回去,变成自然的格式。
比如:从豆瓣的示例代码中的summary项内容为:
小王子驾到!大家好,我是小王子,生活在B612星球......你只有在卓越网( www.joyo.com )才能找到我。有缘的话,我们很快就能相见了。\n尼采、纪德、圣......
这中间有很多非文本字符,并且已经被转义成了文本,如果使用第二种方法,效果就是如下图所示。
解析效果图。

由于官方文档中的示例大多以英文为主,而平时的生产环境中我们多用中文,因此,这些问题都是官方文档中没有提到的,遂在此总结。


转自豆瓣:http://www.douban.com/note/240780324/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值