Python编码问题整理

认识常见编码

GB2312是中国规定的汉字编码,也可以说是简体中文的字符集编码

GBK是 GB2312的扩展 ,除了兼容GB2312外,它还能显示繁体中文,还有日文的假名

cp936:中文本地系统是Windows中的cmd,默认codepage是CP936,cp936就是指系统里第936号编码格式,即GB2312的编码。

(当然有其它编码格式:cp950 繁体中文、cp932 日语、cp1250 中欧语言。。。)

Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。

UTF-8(8-bit Unicode Transformation Format)是最流行的一种对 Unicode 进行传播和存储的编码方式。它用不同的 bytes 来表示每一个代码点。ASCII 字符每个只需要用一个 byte ,与 ASCII 的编码是一样的。所以说 ASCII 是 UTF-8 的一个子集。

在开发Python程序的过程中,会涉及到三个方面的编码:

  • Python程序文件的编码
  • Python程序运行时环境(IDE)的编码
  • Python程序读取外部文件、网页的编码

Python程序 文件的编码

例如:

Python2自带的IDE,当创建了一个文件保存的时候提示:

这是因为 Python2 编辑器默认的编码是 ASCII ,它是无法识别中文的,所以会弹出这样的提示。这也是我们在大多情况下写 python2 程序的时候习惯在程序的第一行加上: #coding=utf-8

其实,这里的编码文件是很容易解决的。

Python程序运行时环境( IDE )的编码

执行下面的一段程序。

#coding=utf-8
from selenium import webdriver

driver = webdriver.Firefox()
driver.get("http://www.baidu.com")

# 返回百度页面底部备案信息
text = driver.find_element_by_id("cp").text
print(text)

driver.close()

windows cmd 下执行:

我们要获取的信息是:

©2015 Baidu 使用百度前必读 意见反馈 ICP 030173

Windows cmd  用的是 cp936 ,也就是中文的 GB2312 ,在 GBK 的字符集里没有“ ©”,这就导致通过 GBK 解析的时候出现编码问题。

这就像你在翻译英文的时候,出现了一个单词,这个单词你查遍了牛津大词典都没找到对应的含义解释,那么自然是会有问题的。

那假设,我还就想在 cmd 下执行这个 python 程序了,那么可以去修改 cmd 的默认编码类型为 utf-8 ,对应的编码为 CHCP 65001 utf-8 )。在 cmd  下输入: chcp 65001   命令回车。

然后,修改 cmd 的字体为“ Lucida Console ”,再来执行程序就可以被正确输出了。

Python程序读取外部文件、网页的编码

# 这一块,暂时没有找到合适的例子

查看Python系统编码

查看 Python2  Python3 的系统编码。

Python2:

Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'ascii'

Python3:

Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'

那么如何修改 Python2 的系统编码为 urf-8 呢?

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

所以,在你的程序执行的过程中,遇到下面的报错信息时。

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1....

可以将上面的三行代码加到 Python 程序的头部。

decode()与encode()

  • decode  的作用是将其他编码的字符串转换成  Unicode  编码, eg name.decode( GB2312 ) ,表示将 GB2312 编码的字符串 name 转换成 Unicode 编码。
  • encode  的作用是将 Unicode 编码转换成其他编码的字符串, eg name.encode( GB2312 ) ,表示将 GB2312 编码的字符串 name 转换成 GB2312 编码。

例如,前面获取百度底部信息的例子。我还可以通过 decode() encode() 来解决:

#coding=utf-8
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("http://www.baidu.com")

# 返回百度页面底部备案信息
text = driver.find_element_by_id("cp").text
text2 = text.encode("gbk","ignore").decode("gbk")
print(text2)

这里通过 encode() Unicode 编码转换成 gbk 编码,在转换的过程中通过“ ignore ”忽略掉 gbk 不能识别的字符( ©),然后再把 gbk 转换成 Unicode 编码。当然,这并不是一种完美的方式,毕竟牺牲部分字符串。

chardet模块

chardet 是一个非常优秀的编码识别模块。

通过 pip  安装:

>pip install chardet

使用:

>>> from chardet import detect

>>> a = "中文"

>>> detect(a)
{'confidence': 0.682639754276994, 'encoding': 'KOI8-R'}

大概有 68% 的把握为 KOI8-R编码类型。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章