最近用python编写了一个简单的爬虫工具,用于从google play上获取游戏类应用的信息。在处理和存储爬取的数据时,我被编码问题困扰了一番,于是利用周末时间,深入研究了字符集和字符编码的基础知识。为了加深理解并方便日后参考,我在此记录这些知识。
- 字符集和字符编码的概念
字符集:指一个系统所支持的所有字符的集合。例如,ASCII(美国信息交换标准码)字符集,包含英文字符、阿拉伯数字等可显示字符,以及回车、换行等控制字符。常见的字符集还有GB2312、BIG5和Unicode等。
字符编码:字符集仅仅是字符的集合,它并不涉及字符在计算机中的存储方式。字符编码则定义了字符集中的字符在计算机中的存储和传输规则。
字符集 vs 字符编码:字符集是脱离计算机讨论的字符集合,而字符编码是与计算机直接相关的规则,规定了字符集中的每个字符如何在计算机中存储和传输。
- 常见字符集简介
以下按照出现时间从早到晚介绍几个常见的字符集:
(1) ASCII字符集 & 字符编码
ASCII是最早的字符集和编码,计算机刚出现时就使用ASCII,是目前最通用的单字节编码系统。
ASCII字符集的基本集包含128个字符,包括大小写英文字母、阿拉伯数字和标点符号等可显示字符,以及空格和回车等控制字符;扩展集包含另外128个字符,涵盖部分西欧语言的字符。因此,整个ASCII字符集定义了256个字符。计算机中,一个字节(8个bit)即可编码ASCII字符集的所有字符,基本集只使用一个字节中的低7位。
ASCII支持的所有字符及编码规则可以通过http://www.asciitable.com/查看。
(2) GB*字符集 & 字符编码
在介绍具体字符集前,先介绍多字节编码系统(MBCS)。由于许多地区的语言无法用ASCII表示,而ASCII流行,新的字符编码必须与ASCII兼容,因此MBCS设计为:ASCII基本集字符仍使用与ASCII相同的编码规则,如果第一个字节的值小于0x80,则表示一个ASCII基本集字符;如果大于或等于0x80,则与下一个字节一起表示一个ASCII基本集外的字符。MBCS不是特定的编码,而是一个统称,包括GB***、BIG***等。
微软Windows中的“ANSI”不是特定编码,而是指“当前地区使用的默认字符编码”,例如在中国,ANSI指GBK。
常见的中文字符集有GB2312和GBK。GB指代国标,全称中华人民共和国国家标准,2312是标准号。GB2312(具体为GB 2312-80)中文全称为“信息交换用汉字编码字符集 基本集”,主要用于中国大陆和新加坡等地。GB2312涵盖了大部分汉字,但无法处理一些生僻字。
作为GB2312的扩展,微软利用GB2312中未使用的编码空间,制定了GBK字符编码。“K”指代“扩展”中的“扩”。GBK收录了更多的汉字字符,但编码方式与GB 13000.1-93不同。GBK不是国家标准,而是由国家技术监督局标准化司和电子工业部科技与质量监督司发布的技术规范指导性文件。
(3) BIG***字符集 & 字符编码
常见的有BIG5字符集及编码。BIG5是繁体中文社区中最常用的字符集标准,主要用于港澳台等繁体中文通行区。BIG5不是国家标准,而是业界常用标准。BIG5编码属于MBCS,使用两个字节存储一个字符,并有“造字区”供用户自定义字符。例如倚天中文系统、Windows等操作系统支持BIG5字符集和编码,并定义了自己的造字区,因此BIG5有多个派生版本。
樱桃企业网站管理系统全DIV+CSS模板,多浏览器适应,完美兼容IE6-IE8,火狐,谷歌等符合标准的浏览器,模板样式集中在一个CSS样式中,内容与样式完全分离,方便网站设计人员开发模板与管理。系统较为安全,以设计防注入,敏感字符屏蔽,适合新手自己操作修改。新闻,产品,单页独立关键字设计,提高搜索引擎收录。 后台地址:admin/login.asp 后台账户:admin 密码:admin (
(4) Unicode字符集及其字符编码
像中文使用的GB2312、BIG5一样,其他非英文国家和地区也创造了自己的字符集和编码。这些在当地使用没有问题,但在互联网传播时会变成乱码。Unicode就是为了解决这个问题而创建的。Unicode字符集定义了超过10万个字符,几乎涵盖了所有国家和地区的字符,并还在不断收录新字符。Unicode是一个字符集,不是字符编码规则,而UTF-8、UTF-16和UTF-32是Unicode字符集的几种编码规则。
UTF-32规定所有Unicode字符使用32个bit(4个字节)存储,足以编码目前所有Unicode字符。UTF-16对Unicode索引在2^16以内的字符使用2个字节存储,对索引在2^16以外的字符使用特殊技巧处理。UTF-32和UTF-16有固定字节数存储字符的优点,但由于计算机存储的大端和小端规则不同,需要在文件开头定义BOM(Byte Order Mark)来判断文件的存储规则。
UTF-8是Unicode字符集的另一种编码方式,使用1到4个字节编码Unicode字符。UTF-8与ASCII兼容,ASCII字符在UTF-8编码时与ASCII编码一致。UTF-8的编码规则可以简单描述为:单字节符号的第一位设为0,后面7位为Unicode码;对于n字节符号(n>1),第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位设为10,剩余位为Unicode码。
在Windows记事本中,“Unicode”和“Unicode big endian”选项实际上指代的是UCS-2编码方式,分别以小端和大端规则存储。
- Python 常见字符编码问题
介绍完字符集和字符编码的基础知识,下面总结几个Python中常见的字符编码问题。
注释头部的“# -- coding: xxxx --”:告知Python解释器程序文件中使用的编码方式,以便正确理解其中的字符串。保存文件时应与注释头中声明的编码方式一致,否则可能导致Python解释器以错误的编码规则解释字符,产生非预期结果。
unicode类和str类:unicode是“字符串”,str是“字节串”。以汉字“大”为例,声明unicode对象的方法为“u = u'大'”,声明str对象的方法为“s = '大'”。声明str对象时,Python根据文件头部的coding注释对字符进行编码,得到的字节串就是str的值。使用len()函数获取unicode对象的长度为1,而在UTF-8编码下,str对象的长度为3。

encode() vs decode():对unicode对象使用encode()方法可将其按照某种编码规则编码,返回编码后的str对象;对str对象使用decode()方法可将其按照某种编码规则解码,返回解码后的unicode对象。

文件读写:使用open()函数打开文件并用read()方法读取,得到的是str对象(字节串),可使用decode方法得到相应的unicode字符串。使用write()方法写文件时,如果参数是str对象,则直接写入字节串;如果是unicode对象,则使用.py文件头部的coding注释声明的编码进行encode操作,然后写入相应的字节串。
decode('unicode-escape'):常常令人迷惑。例如,
'\u5927'.decode('unicode-escape')相当于取unicode字符集的第5927(16进制)号字符(https://www.php.cn/link/37c771d1bc9e621efc6c6c03c864f981。
转载请注明出处。请前往 Tiga on Tech 查看原文以及更多有趣的技术文章。









