Python編碼問題整理【轉(zhuǎn)】
認(rèn)識(shí)常見編碼
GB2312是中國規(guī)定的漢字編碼,也可以說是簡體中文的字符集編碼
GBK 是 GB2312的擴(kuò)展 ,除了兼容GB2312外,它還能顯示繁體中文,還有日文的假名
cp936:中文本地系統(tǒng)是Windows中的cmd,默認(rèn)codepage是CP936,cp936就是指系統(tǒng)里第936號(hào)編碼格式,即GB2312的編碼。
(當(dāng)然有其它編碼格式:cp950 繁體中文、cp932 日語、cp1250 中歐語言。。。)
Unicode是國際組織制定的可以容納世界上所有文字和符號(hào)的字符編碼方案。UTF-8、UTF-16、UTF-32都是將數(shù)字轉(zhuǎn)換到程序數(shù)據(jù)的編碼方案。
UTF-8 (8-bit Unicode Transformation Format)是最流行的一種對(duì) Unicode 進(jìn)行傳播和存儲(chǔ)的編碼方式。它用不同的 bytes 來表示每一個(gè)代碼點(diǎn)。ASCII 字符每個(gè)只需要用一個(gè) byte ,與 ASCII 的編碼是一樣的。所以說 ASCII 是 UTF-8 的一個(gè)子集。
在開發(fā)Python程序的過程中,會(huì)涉及到三個(gè)方面的編碼:
- Python程序文件的編碼
- Python程序運(yùn)行時(shí)環(huán)境(IDE)的編碼
- Python程序讀取外部文件、網(wǎng)頁的編碼
Python程序文件的編碼
例如:
Python2自帶的IDE,當(dāng)創(chuàng)建了一個(gè)文件保存的時(shí)候提示:

這是因?yàn)镻ython2編輯器默認(rèn)的編碼是ASCII,它是無法識(shí)別中文的,所以會(huì)彈出這樣的提示。這也是我們?cè)诖蠖嗲闆r下寫python2程序的時(shí)候習(xí)慣在程序的第一行加上:#coding=utf-8
其實(shí),這里的編碼文件是很容易解決的。
Python程序運(yùn)行時(shí)環(huán)境(IDE)的編碼
執(zhí)行下面的一段程序。
#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下執(zhí)行:

我們要獲取的信息是:
?2015 Baidu 使用百度前必讀 意見反饋 京ICP證030173號(hào)
Windows cmd 用的是cp936,也就是中文的GB2312,在GBK的字符集里沒有“?”,這就導(dǎo)致通過GBK解析的時(shí)候出現(xiàn)編碼問題。
這就像你在翻譯英文的時(shí)候,出現(xiàn)了一個(gè)單詞,這個(gè)單詞你查遍了牛津大詞典都沒找到對(duì)應(yīng)的含義解釋,那么自然是會(huì)有問題的。
那假設(shè),我還就想在cmd下執(zhí)行這個(gè)python程序了,那么可以去修改cmd的默認(rèn)編碼類型為utf-8,對(duì)應(yīng)的編碼為CHCP 65001(utf-8)。在cmd 下輸入:chcp 65001 命令回車。

然后,修改cmd的字體為“Lucida Console”,再來執(zhí)行程序就可以被正確輸出了。

Python程序讀取外部文件、網(wǎng)頁的編碼
#這一塊,暫時(shí)沒有找到合適的例子
查看Python系統(tǒng)編碼
查看Python2 或Python3的系統(tǒng)編碼。
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的系統(tǒng)編碼為urf-8呢?
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
所以,在你的程序執(zhí)行的過程中,遇到下面的報(bào)錯(cuò)信息時(shí)。
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1....
可以將上面的三行代碼加到Python程序的頭部。
decode()與encode()
- decode 的作用是將其他編碼的字符串轉(zhuǎn)換成 Unicode 編碼,eg name.decode(“GB2312”),表示將GB2312編碼的字符串name轉(zhuǎn)換成Unicode編碼。
- encode 的作用是將Unicode編碼轉(zhuǎn)換成其他編碼的字符串,eg name.encode(”GB2312“),表示將GB2312編碼的字符串name轉(zhuǎn)換成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編碼轉(zhuǎn)換成gbk編碼,在轉(zhuǎn)換的過程中通過“ignore”忽略掉gbk不能識(shí)別的字符(?),然后再把gbk轉(zhuǎn)換成Unicode編碼。當(dāng)然,這并不是一種完美的方式,畢竟?fàn)奚糠肿址?/p>
chardet模塊
chardet是一個(gè)非常優(yōu)秀的編碼識(shí)別模塊。
通過pip 安裝:
>pip install chardet
使用:
>>> from chardet import detect
>>> a = "中文"
>>> detect(a)
{'confidence': 0.682639754276994, 'encoding': 'KOI8-R'}
大概有68%的把握為KOI8-R編碼類型。


浙公網(wǎng)安備 33010602011771號(hào)