python中文编码与json中文输出问题详解


Posted in Python onAugust 24, 2018

前言

python2.x版本的字符编码有时让人很头疼,遇到问题,网上方法可以解决错误,但对原理还是一知半解,本文主要介绍 python 中字符串处理的原理,附带解决 json 文件输出时,显示中文而非 unicode 问题。首先简要介绍字符串编码的历史,其次,讲解 python 对于字符串的处理,及编码的检测与转换,最后,介绍 python 爬虫采取的 json 数据存入文件时中文输出的问题。

参考书籍:Python网络爬虫从入门到实践 by唐松

在python 2或者3 ,字符串编码只有两类 :

(1)通用的Unicode编码;

(2)将Unicode转化为某种类型的编码,如UTF-8,GBK;

1、计算机历史:

计算机只处理数字,因此处理文本时,必须转换成数字才行。

8位(bit)=1字节(byte)=256种不同状态=从000000到111111;

1GB=1024M=1024(1024kb)=1024(1024(1024b));

ASCII编码 是对应英文字符与二进制数字之间的关系;ASCII一共规定了128种,如大写字母A是65,即01000001;可见一字母一字节;

GB2312编码 简体中文常见的编码,两个字节代表一个中文汉字 ,理论上256*256个编码,即可表示65536种中文字;

各国编码不同,为了各国能扩平台进行文本的转换与处理,Unicode就被作为统一码或者单一码。Unicode编码通常是两个字节,unicode与ASCII编码的区别,在于unicode在ASCII编码前加了一个0,即字母A的ASCII编码为01000001,unicode编码即为0000000001000001;但英文字母其实只用一个字节就够了,unicode编码写英文时多了一个字节,浪费存储空间。因而unicode开发了通用转换格式(Unicode Transformation Format(UTF)),常见的有utf-8或者utf-16;

要明白encode()和decode()的区别

encode()的作用是将Unicode编码的字符串转换为其他编码格式。

例如: st1.encode("utf-8") 这句话的作用是将Unicode编码的st1编码为utf-8编码的字符串

decode()的作用是把其他编码格式的字符串转换成Unicode编码的字符串。

例如: st2.decode("utf-8") 这句话的作用是将utf-8编码的字符串st2解码为Unicode编码的字符串

第二,除Unicode编码的字符串以外,任何一种编码的字符串要想转换为其他编码格式,必须先解码后编码

非Unicode编码--> Unicode编码-->非Unicode编码

例如,utf-8编码的字符串st想要转换为gbk编码的字符串,必须经过以下步骤:

st=st.decode("utf-8") #解码为Unicode编码
st=st.encode("gbk") #从Unicode编码编码为gbk编码

第三,我们经常使用的utf-8编码还分为有BOM的和无BOM的。

第四:关于json文件的中文编码。用Python读取Json文件时经常用到json.load()函数,该函数对json文件的格式是有要求的

1)json文件是utf-8 without BOM编码的,那么可以直接用json.load(filename)函数读取json文件的内容

2)json文件是utf-8 with BOM编码的,不能用json.load()函数读取,json.load()不能正确识别

3)json文件时其他编码的,比如gbk, 要把json文件的编码格式作为一个参数传给json.load()

eg. json.load(filename,"gbk")

第五,怎么查看并且设置自己文件的编码呢。

介绍一个个人比较喜欢的工具"Nodtepad++",随便一个软件管家里就与一键安装。

用这个工具你可以方便的查看自己的文件的当前编码,并可以轻松转换成任意其他编码格式

2、python字符编码

参考地址:https://3water.com/article/139878.htm

(1)encode的作用是,将unicode对象编码成其他编码的字符串,str.encode('utf-8'),编码成UTF-8;(2)decode的作用是将其他编码的字符串转换成Unicode编码,str.decode('UTF-8');

  • import chardet 查阅具体的编码类型,chardet.detect(str),但是str不能是unicode编码类型,但是该方法 不接受 本来已经是unicode的编码的 参数,会有TypeError: Expected object of type bytes or bytearray, got: <type 'unicode'>错误;
  • 作为统一标准,unicode不能再被解码,如果UTF-8想转至其他非unicode,则必须(2)先decode 到unicode,在encode到其他非unicode的编码。

爬取网页时,可在F12 elements meta中查看网页编码方式,如图:

python中文编码与json中文输出问题详解

(2)中文,Python中的字典能够被序列化到json文件中存入json

with open("anjuke_salehouse.json","w",encoding='utf-8') as f:
 json.dump(all_house,f,ensure_ascii=False,sort_keys=True, indent=4);
 print(u'加载入文件完成...');

存储数据如图:

python中文编码与json中文输出问题详解

  • dump()的第一个参数是要序列化的对象,第二个参数是打开的文件句柄,注意文件打开open()时加上以UTF-8编码打开,在dump()的时候也加上ensure_ascii=False,不然会变成ascii码写到json文件中json.dump(all_house,f,ensure_ascii=False,sort_keys=True, indent=4)

json.dumps()/json.loads()等用法

json_str = json.dumps(all_house,ensure_ascii=False); #all——books 为列表、字典等python自带的数据结构,将其写成json
#print json_str; #[{"brokername": "王东宇"},{},{}]
new_dict = json.loads(json_str);#主要是读json文件时,需要用到
#print new_dict; #{u'house_area': u'95', u'build_year': u'2005'}
  • json.dumps() 是将一个Python数据结构转换为一个JSON编码的字符串,

{"name": "xiaoming"}

python中文编码与json中文输出问题详解

json.loads() 是将一个JSON编码的字符串(字典形式)转换为一个Python数据结构,{u'name': u'xiaoming'}

python中文编码与json中文输出问题详解

dumps转化后键与值都变成了双引号,而在loads后变成python变量时,元素都变成了单引号,并且字符串前加多了个u。
一般要求当要字符串通过loads转为python数据类型时,得外层用单引号,里面元素key和value用双引号。

  • sort_keys:根据key排序

dump与dumps的区别

  • dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, sort_keys=False, **kw);dump将一个对象序列化存入文件,dump需要一个类似于文件指针的参数(并不是真的指针,可称之为类文件对象),可以与文件操作结合,也就是说可以将dict转成str存入文件中,如json.dump(all_house,f,ensure_ascii=False,sort_keys=True, indent=4)中的f表示一个数据待写入的json文件句柄;
  • dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, sort_keys=False, **kw);而dumps(str)直接给的是str,也就是直接将字典转成str,无需写入文件,类似一个数据格式的转换方法,将python字符串转成json字典。
  • 所以dumps是将dict转化成str格式,loads是将str转化成dict格式。
    dump和load也是类似的功能,只是与文件操作结合起来了。

(3)中文存入txt

f=open('net_saving_data.txt','w',encoding='utf-8');
for item in all_house:
 # house_area=item['house_area'];
 # price=item['price'];
 output='\t'.join([str(item['house_area']),str(item['price']),str(item['build_year']),str(item['house_title'])]);
 f.write(output);
 f.write('\n');
f.close();

python中文编码与json中文输出问题详解

  • 在2.7.15版本的python中,提示错误TypeError: 'encoding' is an invalid keyword argument for this function,无法传入encoding的参数,但是在3.7版本可传入encoding='utf-8'参数,即可对 txt进行中文写入。

!!NOTE

  • 中文写入txt、json文件是无非就是open()文件时,需要添加utf-8,dump()时,需要添加ensure_ascii=False,防止ascii编码,但是刚开始因为python版本是2.7.15,不是3.7,导致存储不成功的时候,一直以为是代码的问题。所以最后发现就是版本的问题,也挺伤的。网上关于中文这个编码问题有很多,但是他们都没有强调python版本的问题!!!其他3.xx的版本没有试过。
  • 读取网页数据的时候,查看网页的charset,及chardet库对编码类型的查询,及时进行decode和encode的编码转化,应该就能避免很多编码问题了。其他的坑以后踩了再补吧。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
详解Python中__str__和__repr__方法的区别
Apr 17 Python
介绍Python中的文档测试模块
Apr 28 Python
python图像处理之镜像实现方法
May 30 Python
Python数据可视化之画图
Jan 15 Python
python flask安装和命令详解
Apr 02 Python
python聚类算法解决方案(rest接口/mpp数据库/json数据/下载图片及数据)
Aug 28 Python
python进程池实现的多进程文件夹copy器完整示例
Nov 27 Python
python给图像加上mask,并提取mask区域实例
Jan 19 Python
Python GUI编程学习笔记之tkinter事件绑定操作详解
Mar 30 Python
在keras下实现多个模型的融合方式
May 23 Python
Python Socket TCP双端聊天功能实现过程详解
Jun 15 Python
opencv实现图像几何变换
Mar 24 Python
详解Django解决ajax跨域访问问题
Aug 24 #Python
Python面向对象之反射/自省机制实例分析
Aug 24 #Python
Python使用装饰器模拟用户登陆验证功能示例
Aug 24 #Python
Python日志模块logging基本用法分析
Aug 23 #Python
Python多继承原理与用法示例
Aug 23 #Python
Python抽象和自定义类定义与用法示例
Aug 23 #Python
Python引用计数操作示例
Aug 23 #Python
You might like
十天学会php(2)
2006/10/09 PHP
PHP 函数语法介绍一
2009/06/14 PHP
PHP实现异步调用方法研究与分享
2011/10/27 PHP
Chrome Web App开发小结
2014/09/04 PHP
php下载远程大文件(获取远程文件大小)的实例
2017/06/17 PHP
PHP魔术方法之__call与__callStatic使用方法
2017/07/23 PHP
Laravel 的数据库迁移的方法
2017/07/31 PHP
PHP 获取 ping 时间的实现方法
2017/09/29 PHP
PHP如何使用JWT做Api接口身份认证的实现
2020/02/03 PHP
jQuery 标题的自动翻转实现代码
2009/10/14 Javascript
jquery蒙版控件实现代码
2010/12/08 Javascript
js获取触发事件元素在整个网页中的绝对坐标(示例代码)
2013/12/13 Javascript
jquery通过visible来判断标签是否显示或隐藏
2014/05/08 Javascript
JS实现Fisheye效果动感放大菜单代码
2015/10/21 Javascript
bootstrap-wysiwyg结合ajax实现图片上传实时刷新功能
2016/05/27 Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
2017/01/11 Javascript
angularjs实现搜索的关键字在正文中高亮出来
2017/06/13 Javascript
JavaScript中递归实现的方法及其区别
2017/09/12 Javascript
vue中多个倒计时实现代码实例
2019/03/27 Javascript
微信小程序登录对接Django后端实现JWT方式验证登录详解
2019/07/29 Javascript
解决Vue大括号字符换行踩的坑
2020/11/09 Javascript
浅谈vue在html中出现{{}}的原因及解决方式
2020/11/16 Javascript
Python写入数据到MP3文件中的方法
2015/07/10 Python
python删除服务器文件代码示例
2018/02/09 Python
如何基于Python + requests实现发送HTTP请求
2020/01/13 Python
纯CSS3实现图片无间断轮播效果
2016/08/25 HTML / CSS
详解CSS3+JS完美实现放大镜模式
2020/12/03 HTML / CSS
美国知名的隐形眼镜电商:Contacts America
2019/11/19 全球购物
《永远的白衣战士》教学反思
2014/04/25 职场文书
人力资源求职信
2014/05/25 职场文书
工作检讨书500字
2014/10/19 职场文书
2014年组织委员工作总结
2014/12/01 职场文书
国家助学贷款承诺书
2015/04/30 职场文书
Python使用protobuf序列化和反序列化的实现
2021/05/19 Python
MyBatis 动态SQL全面详解
2021/10/05 MySQL
阿里云服务器(windows)手动部署FTP站点详细教程
2022/08/05 Servers