python中文编码与json中文输出问题详解
作者:msay 发布时间:2021-03-15 17:57:18
前言
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://www.jb51.net/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中查看网页编码方式,如图:
(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'加载入文件完成...');
存储数据如图:
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"}
json.loads() 是将一个JSON编码的字符串(字典形式)转换为一个Python数据结构,{u'name': u'xiaoming'}
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();
在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的编码转化,应该就能避免很多编码问题了。其他的坑以后踩了再补吧。
来源:https://www.cnblogs.com/mingjiatang/p/9527345.html


猜你喜欢
- 引言如今 Python 成为机器学习和大量使用数据操作的科学领域的主流语言; 它拥有各种深度学习框架和完善的数据处理和可视化工具。但是,Py
- 功能是打开本机端口,映射到指定IP的端口场景1本机:tomcat启动8080,通过本端口工具打开80,指向到tomcat的8080。请求本机
- 今天做项目时,有一个这样的需求,需要动态删除的Tab,比如:可以删除某一个,可以删除多个。每一个Tab对应一个iframe。本来我的代码是这
- 在简略的说之前,首先要对RW锁的结构有一个大致的了解type RWMutex struct { w
- 目录一、字符串:二、使用:(1)空字符串和 len( ) 函数(2)转译字符( \ )(3)字符串拼接(4)字符串复制(
- 今天填一个坑,俄罗斯方块!!俄罗斯方块的移动不难实现,但是旋转就不太容易实现,究其原因是因为Python中没有数组这种数据结构,所以不能用矩
- 程序流Python 解释器在其最简单的级别,以类似的方式操作,即从程序的顶端开始,然后一行一行地顺序执行程序语句。例如,清单 1 展示了几个
- 本文实例讲述了python中的lambda表达式用法。分享给大家供大家参考,具体如下:这里来为大家介绍一下lambda函数。lambda 函
- pyhook下载:http://sourceforge.net/projects/pyhook/files/pyhook/1.5.1/pyh
- 前言 BeautifulSoup是主要以解析web网页的Python模块,它会提供一些强大的解释器,以解
- 在计算机软件领域,缓存(Cache)指的是将部分数据存储在内存中,以便下次能够更快地访问这些数据,这也是一个典型的用空间换时间的例子。一般用
- 问题起因最近要将一个文本分割成好几个topic,每个topic设计一个regressor,各regressor是相互独立的,最后汇总所有to
- 如下所示:"""提取文档数超过10000的数据按照某个字段的值具有唯一性进行升序,按照@timestamp进行
- 环境:Zend Studio 8.0Zend Studio是PHP开发者的首选开发工具,其地位相当于微软开发工具中的Visual Studi
- 本文主要介绍了Opencv图片生成视频,分享给大家,具体如下:生成视频import random as rdimport cv2 as cv
- Python FastAPI请求参数传递FastAPI多参数传递类型FastAPI通过模板来匹配URL中的参数列表,大致有如下三类方式传递参
- 业务场景使用elasticsearch作为全文搜索引擎,对标题、内容等,实现智能搜索、输入提示、拼音搜索等elasticsearch索引与数
- 1. Vue 路由权限控制一般有2种方法a、路由元信息(meta)b、动态加载菜单和路由(addRoutes)2 路由元信息(meta)来进
- 本文为大家分享了mysql 5.7.17 winx64解压版安装配置方法,供大家参考,具体内容如下一、下载下载地址二、配置1. 解压下载的m
- 本文实例讲述了Python基础之循环语句用法。分享给大家供大家参考,具体如下:while 循环Python中while语句的一般形式:whi