python2.x版本的字符编码有时让人很头疼,遇到问题,网上方法能够解决错误,但对原理仍是只知其一;不知其二,本文主要介绍 python 中字符串处理的原理,附带解决 json 文件输出时,显示中文而非 unicode 问题。首先简要介绍字符串编码的历史,其次,讲解 python 对于字符串的处理,及编码的检测与转换,最后,介绍 python 爬虫采起的 json 数据存入文件时中文输出的问题。
参考书籍:Python网络爬虫从入门到实践 by唐松python
在python 2或者3 ,字符串编码只有两类 :json
(1)通用的Unicode编码;
(2)将Unicode转化为某种类型的编码,如UTF-8,GBK;网络
计算机只处理数字,所以处理文本时,必须转换成数字才行。
8位(bit)=1字节(byte)=256种不一样状态=从000000到111111;
1GB=1024M=1024(1024kb)=1024(1024(1024b));数据结构
ASCII编码 是对应英文字符与二进制数字之间的关系;ASCII一共规定了128种,如大写字母A是65,即01000001;可见一字母一字节;ui
GB2312编码 简体中文常见的编码,两个字节表明一个中文汉字 ,理论上256*256个编码,便可表示65536种中文字;this
各国编码不一样,为了各国能扩平台进行文本的转换与处理,Unicode就被做为统一码或者单一码。Unicode编码一般是两个字节,unicode与ASCII编码的区别,在于unicode在ASCII编码前加了一个0,即字母A的ASCII编码为01000001,unicode编码即为00000000
01000001;但英文字母其实只用一个字节就够了,unicode编码写英文时多了一个字节,浪费存储空间。于是unicode开发了通用转换格式(Unicode Transformation Format(UTF)),常见的有utf-8或者utf-16;编码
参考地址:https://www.jb51.net/article/139878.htm.net
(1)encode的做用是,将unicode对象编码成其余编码的字符串,str.encode('utf-8'),编码成UTF-8;(2)decode的做用是将其余编码的字符串转换成Unicode编码,str.decode('UTF-8');指针
chardet.detect(str)
,可是str不能是unicode编码类型,可是该方法 不接受 原本已是unicode的编码的 参数,会有TypeError: Expected object of type bytes or bytearray, got: <type 'unicode'>错误;爬取网页时,可在F12 elements meta中查看网页编码方式,如图:code
(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'加载入文件完成...');
存储数据如图:
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.loads() 是将一个JSON编码的字符串(字典形式)转换为一个Python数据结构,{u'name': u'xiaoming'}
dumps转化后键与值都变成了双引号,而在loads后变成python变量时,元素都变成了单引号,而且字符串前加多了个u。
通常要求当要字符串经过loads转为python数据类型时,得外层用单引号,里面元素key和value用双引号。
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字典。(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();
TypeError: 'encoding' is an invalid keyword argument for this function
,没法传入encoding的参数,可是在3.7版本可传入encoding='utf-8'参数,便可对 txt进行中文写入。