字符编码:
一、字符编码的历史:
# 纸带打孔机 编程
# 汇编语言+机器语言
# C、lisp、Fortran -- Python C++ Java
基本点:计算机里所有数据存储、计算,都是通过二进制处理。
二进制: 0b01100001
十进制: int(0b0110001) -> 97
字符: chr(97) -> 'a'
ASCII表:美国标准信息交换码,只能表示常用的字母、数字和普通符号, 0~127之间,一个字符 占 1 个字节。
latin-1: 在ASCII基础上扩展了127个,包含了西方文字,德文、法文...
gb2312: 在ASCII基础上进行扩展,可以表示简体中文(gb2312->gbk->gb18030),一个汉字 2 个字节
Big5 : 在ASCII基础上进行扩展,表示繁体中文..
shift-jis : 在ASCII基础上进行扩展,日文..
几乎每个国家都有自己的编码表,导致文字交流不方便。
注意:如果输出字符时,没有对应的编码表支持,就会出现"乱码"。
为了解决编码不一致的问题,国际标准组织制定了一套新的编码 Unicode,给全世界每一个字符单独指定了一个新的二进制方式。
但是Unicode有个缺点,每个字符占用 3~4个字节,比较浪费空间。
于是在Unicode基础上进行了升级更新: utf-8 编码(可变长的Unicode),一个字母占1个字节,一个汉字占3个字节。
所以utf-8现在是世界上最流行应用最广泛的编码,90%以上的网页字符编码 默认为 utf-8,所有的Linux终端编码默认是utf-8
简体中文Windows 终端默认编码是 gbk,但是可以通过 chcp 65001 修改为 utf-8
二、Python中的字符编码和类型对比:
Python3 中:
Unicode编码字符串,是 str 类型
非Unicode编码字符串,是 bytes 类型
Python2 中(了解):
Unicode编码字符串,是 unicode 类型
非Unicode编码字符串, 是 str 类型
编码统一处理口诀:任何操作系统下的任何编程语言的任何编码,都可以和Unicode互相转换。
utf8_str --> gbk_str
# 对 utf-8 字符串按自身编码进行解码,返回 Unicode字符串
unicode_str = utf8_str.decode("utf-8")
# 对 Unicode字符串 按指定编码进行编码,返回 编码后的字符串
gbk_str = unicode_str.encode("gbk")
三、Python爬虫程序需要处理的编码场景:
1. 发送请求,获取网页字符串(不同的网页,字符串编码可能不一样,编码统一)
2. 数据解析过程中,需要处理的字符串编码(编码统一)
3. 将字符串保存到文件、数据库时(编码统一)
四、在python解释器 终端里创建字符串的编码:
Python3:Unicode编码
Python2:根据操作系统,简体中文Windows -gbk, Linux - utf-8
iPython2里, 全部统一为 utf-8
五、在Python代码文件里创建的字符串编码:
Python3:Unicode编码
Python2:根据操作系统,简体中文Windows - gbk, Linux - utf-8
iPython2里, 全部统一为 utf-8
六:代码文件头部编码声明:
Python3 的代码文件的文字,按utf-8保存
Python2 的代码文件文字,默认按 ascii 保存,所以需要手动声明按 utf-8 保存代码文字
# -*- coding:utf-8 -*-
表示python代码文件里面文字按 utf-8 保存
七、网页字符串编码:
/html/head/meta/charset 指定的当前网页的编码,通过requests模块获取的网页字符串,就是该编码的字符串。
八、将 Unicode字符串数据 保存到文件中方法:
1. 在保存Unicode字符串时,手动编码转换再写入(这种方式不会触发解释器编码默认转换)
Python3:
unicode_str = "你好"
with open("test.txt", "wb") as f:
f.write(unicode_str.encode("utf-8"))
Python2:
unicode_str = u"你好"
with open("test.txt", "wb") as f:
f.write(unicode_str.encode("utf-8"))
2. 在保存Unicode字符串时,通过 open()方法的 encoding 参数指定编码(这种方式不会触发解释器编码默认转换)
Python3:
unicode_str = "你好"
with open("test.txt", "w", encoding="utf-8") as f:
f.write(unicode_str)
Python2:
Python2的 open() 方法默认没有encoding参数,但是可以通过 codecs 模块支持。
import codecs
unicode_str = "你好"
with codecs.open("test.txt", "w", encoding="utf-8") as f:
f.write(unicode_str)
3. 直接保存Unicode字符串到文件中,如果 既没有通过encode编码,也没有通过encoding参数指定编码,则触发解释器编码默认转换。
Python会按照默认的解释器编码进行转码处理,再写入文件。
Python3:可以直接写入Unicode到本地文件,默认文件编码为 utf-8,因为Python3的解释器编码是 utf-8
unicode_str = "你好"
with open("test.txt", "w") as f:
f.write(unicode_str)
Python2:可以直接写入Unicode到本地文件,可能会报出 UnicodeEncodeError,因为Python2的解释器编码默认是 ascii
只能对普通英文字母、数字和字符进行编码转换,如果Unicode里有中文,则编码失败(因为 ascii 不支持处理中文)
# 解决方案:将Python2的解释器编码修改为 utf-8,这样就可以写入任意的Unicode字符串
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
unicode_str = u"你好"
with open("test.txt", "w") as f:
f.write(unicode_str)
九、文件编码:
1. 当第一次写入一个字符串到文件中时,该文件编码等同于字符串编码
2. 当第二次写入的字符串编码,和第一次写入字符串编码不一致时,文件编码被会修改,会导致之前的数据全部变成乱码。
记住:不要在同一个文件中,写入不同编码的字符串。一定要做编码统一。