Python语言在网络爬虫领域应用的十分广泛。在爬虫的应用程序中,我们需要对网页上获取的数据进行处理,其中字符的编码、解码常常让人感到困惑:ASCII码、Unicode、字符编码什么的,很多朋友一直为此头大,那么,我们就分上、下两集来专门深入剖析这些内容。

先开始我们不讲编程,不堆概念,我们讲讲故事:说说字符编码是如何变成今天这样的

关于字符编码的概念太多太杂,当ASCII、GB2312、Unicode、UTF-8、UTF-16、编码、解码等诸多名词一股脑堆上来时,确实容易让人迷糊。

为了把这些问题讲清楚,我们从历史维度,在时间轴上梳理计算机在不同语言国家不断发展的过程,以此来彻底搞清楚这些概念。

1.字符编码与解码是什么

计算机自己能理解的“语言”是二进制数,最小的信息标识是二进制位,8个二进制位表示一个字节;而我们人类所能理解的语言文字则是一套由英文字母、汉语汉字、标点符号字符、阿拉伯数字等等很多的字符构成的字符集。如果要让计算机来按照人类的意愿进行工作,则必须把人类所使用的这些字符集转换为计算机所能理解的二级制码,这个过程就是编码,他的逆过程称为解码。

2.ASCII到Unicode的演进过程

计算机最开始在美国被发明使用,需要编码的字符集并不是很大,无外乎英文字母、数字和一些简单的标点符号,因此采用了一种单字节编码系统。在这套编码规则中,人们将所需字符集中的字符一一映射到128个二进制数上,这128个二进制数最高位为0,利用剩余低7位组成00000000~01111111(0X00~0X7F)。

0X00到0X1F这32个二进制数来对控制字符或通信专用字符(如LF换行、DEL删除、BS退格)进行编码,0X20到0X7F共96个二进制数用来对阿拉伯数字、英文字母大小写和下划线、括号等符号进行编码。将这套字符集映射到0X00~0X7F二进制码的过程就称为基础ASCII编码,通过这个编码过程,计算机就将人类的语言转化为自己的语言存储起来;反之,从磁盘中读取二级制数并转化为字母数字等字符以供显示的过程就是解码了。

随着计算机被迅速推广使用,欧洲非英语国家的人们发现这套由美国人设计的字符集不够用了,比如一些带重音的字符、希腊字母等都不在这个字符集中,于是扩充了ASCII编码规则,将原本为0的最高位改为1,因此扩展出了10000000~11111111(0X80~0XFF)这128个二进制数。这其中,最优秀的扩展方案是ISO 8859-1,通常称之为Latin-1。Latin-1利用128~255这128个二进制数,包括了足够的附加字符集来涵盖基本的西欧语言,同时在0~127的范围内兼容ASCII编码规则。

随着使用计算机的国家越来越多,自然而然需要编码的字符集就越来越庞大,早先的ASCII编码字符集由于受到单字节的限制,其容量就远远不够了,比方说面对成千上万的汉字,其压力可想而知。因此中国国家标准总局发布了一套《信息交换用汉字编码字符集》的国家标准,其标准号就是GB 2312—1980。这个字符集共收入汉字6763个和非汉字图形字符682个,采用两个字节对字符集进行编码,并向下兼容ASCII编码方式。简言之,整个字符集分成94个区,每区有94个位,分别用一个字节对应表示相应的区和位。每个区位对应一个字符,因此可用所在的区和位来对汉字进行两字节编码。再后来生僻字、繁体字及日韩汉字也被纳入字符集,就又有了后来的GBK字符集及相应的编码规范,GBK编码规范也是向下兼容GBK2312的。

在中国发展的同时,计算机在全世界各个国家不断普及,不同的国家地区都会开发出自己的一套编码系统,因此编码系统五花八门,这时候问题就开始凸显了,特别是在互联网通信的大环境下,装有不同编码系统的计算机之间通信就会彼此不知道对方在“说”些什么,按照A编码系统的编码方式将所需字符转换成二进制码后,在B编码系统的计算机上解码是无法得到原始字符的,相反会出现一些出人意料的古怪字符,这就是所谓的乱码。

那么统一字符编码的需求就迫切摆在了大家眼前,为了实现跨语言、跨平台的文本转换和处理需求,ISO国际标准化组织提出了Unicode的新标准,这套标准中包含了Unicode字符集和一套编码规范。Unicode字符集涵盖了世界上所有的文字和符号字符,Unicode编码方案为字符集中的每一个字符指定了统一且唯一的二进制编码,这就能彻底解决之前不同编码系统的冲突和乱码问题。这套编码方案简单来说是这样的:编码规范中含有17个组(称为平面),每一个组含有65536个码位(例如组0就是0X0000~0XFFFF),每一个码位就唯一对应一个字符,大部分的字符都位于字符集平面0的码位中,少量位于其他平面。

3.字符编码和字符代码的概念区分

既然提到了Unicode编码,那么常常与之相伴的UTF-8,UTF-16编码方案又是什么?其实到目前为止我们都一直混淆了两个概念,即字符代码和字符编码,字符代码是特定字符在某个字符集中的序号,而字符编码是在传输、存储过程当中用于表示字符的以字节为单位的二进制序列。ASCII编码系统中,字符代码和字符编码是一致的,比如字符A,在ASCII字符集中的序号,也就是所谓的字符代码是65,存储在磁盘中的二进制比特序列是01000001(0X41,十进制也是65),另外的,如在GB2312编码系统中字符代码和字符编码的值也是一致的,所以无形之中我们就忽略了二者的差异性。

而在Unicode标准中,我们目前使用的是UCS-4,即字符集中每一个字符的字符代码都是用4个字节来表示的,其中字符代码0~127兼容ASCII字符集,一般的通用汉字的字符代码也都集中在65535之前,使用大于65535的字符代码,即需要超过两个字节来表示的字符代码是比较少的。因此,如果仍然依旧采用字符代码和字符编码相一致的编码方式,那么英语字母、数字原本仅需一个字节编码,目前就需要4个字节进行编码,汉字原本仅需两个字节进行编码,目前也需要4个字节进行编码,这对于存储或传输资源而言是很不划算的。

因此就需要在字符代码和字符编码间进行再编码,这样就引出了UTF-8、UTF-16等编码方式。基于上述需求,UTF-8就是针对位于不同范围的字符代码转化成不同长度的字符编码,同时这种编码方式是以字节为单位,并且完全兼容ASCII编码,即0X00-0X7F的字符代码和字符编码完全一致,也是用一个字节来编码ASCII字符集,而常用汉字在Unicode中的字符代码是4E00-9FA5,在文末的对应关系中我们看到是用三个字节来进行汉字字符的编码。UTF-16同理,就是以16位二进制数为基本单位对Unicode字符集中的字符代码进行再编码,原理和UTF-8一致。

因此,我们可以看出,在目前全球互联的大背景下,Unicode字符集和编码方式解决了跨语言、跨平台的交流问题,同时UTF-8等编码方式又有效的节约了存储空间和传输带宽,因而受到了极大的推广应用。

我想,通过讲清楚字符编码的发展历史,容易让人明白为什么某一时刻就出现了某种编码方式,搞清楚了来龙去脉,对字符编码就好理解了。

那么在下集里,我们会再介绍python中字符编码、解码的具体编程技巧,我们下期再见,bye~

附表:Unicode字符代码与UTF-8编码的对应关系

0000 0000-0000 007F | 0xxxxxxx

0000 0080-0000 07FF | 110xxxxx 10xxxxxx

0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx

0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

python字符编码使用的是什么编码_不可不知的Python字符编码使用技巧(上)相关推荐

  1. python对浮点类型的数据进行格式化_(自用)Python Log2 数据类型、字符编码、格式化...

    数据类型 1.整数 十六进制可以使用0x+数字0-9(字母a-f). 2.浮点数 一般使用科学计数法,用e代替10,比如1.2e5,为1.2×10^5. 3.字符串 可以使用单引号' ',或者双引号& ...

  2. python json传参数可以传对象吗_廖雪峰的python系列教程(52)——IO编程之序列化...

    序列化 在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict: d = dict(name='Bob', age=20, score=88) 可以随时修改变量,比如把name改成'Bil ...

  3. python对浮点类型的数据进行格式化_全网最细 Python 格式化输出用法讲解(推荐)...

    免费资源网 - https://freexyz.cn/ 一.使用 print() 函数 在 Python 中,print() 函数支持格式化输出,与 C 语言的 printf 类似. 1. 格式化输出 ...

  4. 为什么python打开pygame秒关闭后在运行_当我运行Python程序时,pygame窗口打开片刻,然后退出 - python...

    我是一个刚开始尝试通过在线课程使用python和pygame制作游戏的程序员.但是,当我运行以下代码时,pygame窗口将打开一秒钟,然后关闭. import pygame pygame.init() ...

  5. python的运算符号使等式成立_你所不知道的 Python 冷知识!(二)(建议收藏)

    首发于微信公众号:Python编程时光 ' 每周三更新五个冷知识,欢迎前往订阅! 01. 交互式"_"操作符 对于 _ ,我想很多人都非常熟悉. 给变量取名好艰难,用 _: 懒得长 ...

  6. 零基础python入门密歇根大学安娜堡分校_零基础:Python入门,看这篇就够了~ 王磊...

    Python在设计上坚持了清晰划一的风格,这使得Python成为一门易读.易维护,并且被大量用户所欢迎的.用途广泛的语言. 设计者开发时总的指导思想是,对于一个特定的问题,只要有一种最好的方法来解决就 ...

  7. python 函数调用 不允许关键字参数_你所不知道的Python|函数参数的演进之路

    原标题:你所不知道的Python|函数参数的演进之路 函数参数处理机制是Python中一个非常重要的知识点,随着Python的演进,参数处理机制的灵活性和丰富性也在不断增加,使得我们不仅可以写出简化的 ...

  8. python编程快速上手-----让繁琐工作自动化_每周一书《Python编程快速上手 让繁琐工作自动化》分享!...

    内容简介 如今,人们面临的大多数任务都可以通过编写计算机软件来完成.Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.通过Python编程,我们能够解决现实生活中的很多任务. 本书是 ...

  9. python 用if判断一个数是不是整数_五天学会Python基础02(下)

    函数和模块的使用 在讲解本章节的内容之前,我们先来研究一道数学题,请说出下面的方程有多少组正整数解. 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案.想到这一点问题的答案就呼之 ...

最新文章

  1. 新浪微博应用 IE下面框架嵌套框架的问题解决
  2. laravel--基础知识
  3. ap忘记管理ip地址怎么办_什么是无线AP?胖瘦AP如何区分?
  4. [LeetCode]Count of Range Sum
  5. c语言单片机4*4键盘程序,求51单片机矩阵4*4键盘程序,P0口接一个数码管,P3口接矩阵键盘,C语言的...
  6. 【spring学习笔记】(二)Spring MVC注解配置 参数转换注解@RequestMapping@RequestParam、@PathVariable@MatrixVariable
  7. VS2013支持多字节
  8. java rmi 入门实例
  9. C语言中变量的储存类别
  10. nodejs gulp less编辑
  11. LaTeX常用的符号
  12. js 返回值提示框不提示
  13. 手把手教你用Python网络爬虫实现起点小说下载
  14. 微信端input输入框在ios手机上连续输入卡顿
  15. PMP|项目管理过程中,怎么识别风险?
  16. InstallShield vs2015 的安装与激活
  17. 第13课:生活中的克隆模式——给你一个分身术
  18. Winform从入门到精通(17)——PictureBox(史上最全)
  19. Android开发之简易音乐播放器(一)
  20. CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins

热门文章

  1. 用HTML+CSS制作前端简历
  2. jupyter下的ipynb文件转换为pdf并且完全保留图片
  3. 有什么软件可以测试自己性格,怎样测试自己的性格
  4. 支持蓝牙的模拟器_仍需打磨:首款Windows 10X模拟器上手
  5. mac mysql my.cnf无效_mac 中 mysql 配置my.cnf无效解决办法-Go语言中文社区
  6. CyberWorld的耗散经济学结构
  7. 拼多多、微信、MT被各大平台的BUG刷屏的2019年1月
  8. 1201:8003 撬锁者
  9. Luogu P2382 化学分子式 (模拟)
  10. 文件上传(upload)