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中无限元素列表的实现方法
Aug 18 Python
Python中列表的一些基本操作知识汇总
May 20 Python
12步入门Python中的decorator装饰器使用方法
Jun 20 Python
python 队列详解及实例代码
Oct 18 Python
python使用turtle库与random库绘制雪花
Jun 22 Python
Python标准库shutil用法实例详解
Aug 13 Python
详解Python requests 超时和重试的方法
Dec 18 Python
python简单贪吃蛇开发
Jan 28 Python
Python 合并多个TXT文件并统计词频的实现
Aug 23 Python
python numpy 反转 reverse示例
Dec 04 Python
Python self用法详解
Nov 28 Python
Python socket如何解析HTTP请求内容
Feb 12 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
非常不错的MySQL优化的8条经验
2008/03/24 PHP
thinkphp框架实现数据添加和显示功能
2016/06/29 PHP
PHP安装memcache扩展的步骤讲解
2019/02/14 PHP
PHP7新功能总结
2019/04/14 PHP
Android中资源文件(非代码部分)的使用概览
2012/12/18 Javascript
jquery实现叠层3D文字特效代码分享
2015/08/21 Javascript
详解Wondows下Node.js使用MongoDB的环境配置
2016/03/01 Javascript
JavaScript数组去重的两种方法推荐
2016/04/05 Javascript
requireJS使用指南
2016/04/27 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
2016/05/17 Javascript
Jquery中map函数的用法
2016/06/03 Javascript
js数组常用操作方法小结(增加,删除,合并,分割等)
2016/08/02 Javascript
详解js运算符单竖杠“|”与“||”的用法和作用介绍
2016/11/04 Javascript
详解Nodejs基于mongoose模块的增删改查的操作
2016/12/21 NodeJs
BootStrapTable 单选及取值的实现方法
2017/01/10 Javascript
angularjs定时任务的设置与清除示例
2017/06/02 Javascript
JS手机端touch事件计算滑动距离的方法示例
2017/10/26 Javascript
JavaScript生成指定范围随机数和随机序列的方法
2018/05/05 Javascript
JavaScript实现与使用发布/订阅模式详解
2019/01/19 Javascript
js this 绑定机制深入详解
2020/04/30 Javascript
手把手带你搭建一个node cli的方法示例
2020/08/07 Javascript
解决vuex改变了state的值,但是页面没有更新的问题
2020/11/12 Javascript
python 字符串格式化代码
2013/03/17 Python
python常见的格式化输出小结
2016/12/15 Python
python3+PyQt5实现自定义窗口部件Counters
2018/04/20 Python
在python 不同时区之间的差值与转换方法
2019/01/14 Python
matplotlib绘制多个子图(subplot)的方法
2019/12/03 Python
python全栈开发语法总结
2020/11/22 Python
Django filter动态过滤与排序实现过程解析
2020/11/26 Python
python实现计算器简易版
2020/12/17 Python
Reebonz中国官网:新加坡奢侈品购物网站
2017/03/17 全球购物
新英格兰最大的特色礼品连锁店:The Paper Store
2018/07/23 全球购物
德国、奥地利和瑞士最大的旅行和度假门户网站:HolidayCheck
2019/11/14 全球购物
软件缺陷的分类都有哪些
2014/08/22 面试题
吃空饷专项治理工作实施方案
2014/03/04 职场文书
消费者理赔投诉书
2015/07/02 职场文书