python 字符编码问题
任何数据在计算机看来都是二进制01组成的代码,所以,为了能将数据存储,就必须转换成二进制的数据,这其中的规则便是编码。 本文所述均为字符编码,那么……就从字符编码的发展讲起吧。在字符编码内首先出现的便是ASCII码了,它存储了128个基本字符,仅需要1byte的数据,基本对应键盘上的大部分字符。很明显,我们在其中找不到我们想要的中文字符,当然,中文也不是128个所能容纳的,那么我们就需要有其他的字符编码。所以就中文而言有了’GB2312’这样的编码,同样地,其他国家也有自己的字符编码。这样问题就来了,因为编码规则不同,所以一个码可能对应多个字符,通过不同编码方式解码出来的文字完全不一样,这样的话就会出现我们常说的乱码问题,而且,同一文章也无法兼容两种文字。为了统一这一标准Unicode应运而生。Unicode是在ASCII编码的基础上进行了扩展,对ASCII兼容,也即,ASCII码的字符的Unicode码是在其基础上加1byte的0,(这1byte的0便是’’(空字符)啦,所以ASCII解码时候完全不影响哒),Unicode采用2byte数据存储,完美解决了各国标准不一的问题。但是另一个问题就产生了,就是上面所说的,ASCII码对应的字符是要两倍的数据,造成了资源的极大浪费(毕竟英语还是使用最广泛的语言啊),因此便有了我们现在最常用的UTF-8编码。UTF-8编码采用1-3byte数据存储字符,ASCII对应那些字符依然只需要1byte,中文等字符采用2-3byte的编码,使资源得到了极大的节约。因此我们在文件中在的字符采用utf-8编码以节省空间,但当我们读取他们的时候,就会重新编码为Unicode码存到内存中,当我们保存它的时候又会编码为utf-8码存到硬盘上。 编码(encode)和解码(decode)的问题困扰了我很久,但把之前学的基础知识梳理一遍后就有了新的发现。首先,任何字符串都一定有一个编码规则,不然这个字符串是不会被计算机所认识的,我们在python中的字符是以Unicode编码存储的,也就是说任何存储在python的字符都是以Unicode码形式存储的,每个字符都对应一个Unicode码,就比如说’\u6587’是完全等价于’文’的:
>>> '\u6587'#后面四位是四个十六进制数,刚好是Unicode码对应的2byte(一个16进制数相当于4个2进制数,也即4bit,2byte需要4个16进制数) '文'
而且,我们也可以用chr(),ord()函数将字符进行与Unicode码的互相转换:
>>> chr(25991)#十进制的25991对应十六进制数就是6587 '文'
当然,python也只是用Unicode码存储str,我们的str还是str,并不是一个bytes,想要将它变成一个bytes就需要调用encode方法:
>>> '文'.encode('utf-8') b'\xe6\x96\x87' #bytes类型,编码之后对应的字节流,’\x??’是转义为16进制数,每个1byte,一共3byte
encode方法是将一个str按照编码方式转化成bytes,这个bytes是我们所看不懂的,但却是文件传输时候所需要的,当我们想要把它再变回str时候是一定要按原来编码方式进行decode,不然就会乱码甚至引发无法解码的错误:
b'\xe6\x96\x87'.decode('GB2312') Traceback (most recent call last): File "<pyshell#9>", line 1, in <module> b'\xe6\x96\x87'.decode('GB2312') UnicodeDecodeError: 'gb2312' codec can't decode byte 0xe6 in position 0: illegal multibyte sequence >>> b'\xe6\x96\x87'.decode('utf8')#这里不区分utf8 utf-8的(大小写也都行) '文'
在spider实战过程中遇到了不少编码问题,刚开始还经常将decode和encode弄混,下面记录下遇到的编码问题:1. bs4库:把修改bs4对象encoding属性当做之后会对其进行encode,后来才明白原来只是申明编码方式,事实上还是将HTML页面(bytes)进行decode,这样才得到我们所能看到的页面,如果申明的编码方式错误便会出现乱码甚至无法decode的情况。2. emoji的处理问题:当时是直接复制过来的,后来才明白是将无法解码的bytes过滤,这样就不会报错了。
non_bmp_map = dict.fromkeys(range(0x10000, sys.maxunicode + 1), 0xfffd) r.text.translate(non_bmp_map)#r.text是待解析的str
1. 解析页面时候遇到“不间断空白符 ”无法解码的问题:将HTML中获得的str中的该字符进行替换
s.string.replace(u'\xa0',u' ')#s.string是待替换文本
阅读更多
- 计算机字符编码问题总析(基于Python)
- $ 专治各种python字符编码问题疑难杂症
- 解决python的中文字符编码问题
- mysql, python,MySQLdb等的字符编码问题
- 【Todo】Python中文及Java中文问题及解决方法总结 & 及各种字符编码问题跟踪贴
- mariadb的python连接,远程连接,字符编码问题总结
- python3 中的Json序列化、反序列化 和 字符编码的问题解决
- python字符编码问题
- Python字符编码问题学习
- 【python】\\u的字符编码问题
- python中字符编码问题详解
- python字符编码问题
- 字符编码和python使用encode,decode转换utf-8, gbk, gb2312的问题
- 做爬虫时候遇到的中文字符编码问题(Python)
- python读取中文字符编码问题
- Python中的字符编码问题encode/decode
- google protocol buffer的字符编码问题(c++/java/python)
- python 字符编码问题
- Python读取文件字符编码问题
- python 字符编码处理问题总结 彻底击碎乱码!