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采用raw_input读取输入值的方法
Aug 18 Python
Python操作列表之List.insert()方法的使用
May 20 Python
用生成器来改写直接返回列表的函数方法
May 25 Python
Python实现读取Properties配置文件的方法
Mar 29 Python
Python操作Sql Server 2008数据库的方法详解
May 17 Python
Python3 itchat实现微信定时发送群消息的实例代码
Jul 12 Python
python web框架 django wsgi原理解析
Aug 20 Python
python操作docx写入内容,并控制文本的字体颜色
Feb 13 Python
TensorFlow2.1.0安装过程中setuptools、wrapt等相关错误指南
Apr 08 Python
使用python+poco+夜神模拟器进行自动化测试实例
Apr 23 Python
opencv 图像腐蚀和图像膨胀的实现
Jul 07 Python
python给list排序的简单方法
Dec 10 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
Home Coffee Roasting
2021/03/03 咖啡文化
PHP操作文件方法问答
2007/03/16 PHP
php数组的一些常见操作汇总
2011/07/17 PHP
PHP 日,周,月点击排行统计
2012/01/11 PHP
再Docker中架设完整的WordPress站点全攻略
2015/07/29 PHP
YII2.0之Activeform表单组件用法实例
2016/01/09 PHP
深入剖析浏览器退出之后php还会继续执行么
2016/05/17 PHP
PHP实现时间比较和时间差计算的方法示例
2017/07/24 PHP
PHP+mysql防止SQL注入的方法小结
2019/04/27 PHP
PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】
2019/06/14 PHP
很酷的javascript loading效果代码
2008/06/18 Javascript
[原创]js获取数组任意个不重复的随机数组元素
2010/03/15 Javascript
jQuery LigerUI 使用教程表格篇(1)
2012/01/18 Javascript
javascript 获取HTML DOM父、子、临近节点
2014/06/16 Javascript
jQuery里filter()函数与find()函数用法分析
2015/06/24 Javascript
初步了解javascript面向对象
2015/11/09 Javascript
jQuery-1.9.1源码分析系列(十)事件系统之事件体系结构
2015/11/19 Javascript
Express的路由详解
2015/12/10 Javascript
原生JS实现圆环拖拽效果
2017/04/07 Javascript
angularjs封装$http为factory的方法
2017/05/18 Javascript
Angular 4.X开发实践中的踩坑小结
2017/07/04 Javascript
浅谈vue2 单页面如何设置网页title
2017/11/08 Javascript
微信小程序实现图片上传、删除和预览功能的方法
2017/12/18 Javascript
vue的token刷新处理的方法
2018/07/17 Javascript
javascript+css实现俄罗斯方块小游戏
2020/06/28 Javascript
Python 爬虫学习笔记之单线程爬虫
2016/09/21 Python
Python实现针对给定字符串寻找最长非重复子串的方法
2018/04/21 Python
python3.4实现邮件发送功能
2018/05/28 Python
Python设计模式之状态模式原理与用法详解
2019/01/15 Python
Python中最大递归深度值的探讨
2019/03/05 Python
Python中利用LSTM模型进行时间序列预测分析的实现
2019/07/26 Python
Python使用sqlite3模块内置数据库
2020/05/07 Python
高中毕业生自我鉴定例文
2013/12/29 职场文书
大学班长的职责
2014/01/27 职场文书
2015年安全生产责任书
2015/01/30 职场文书
保姆聘用合同
2015/09/21 职场文书