任何一種語言、文字、符號等等,計算都是將其以一種相似字典的形式存起來的,好比最先的計算機系統將英文文字轉爲數字存儲(ASCII碼),這種文字與數字(或其餘)一一對應的關係咱們稱之爲編碼。因爲ASCII碼只包含了大小寫英文字母、數字和一些符號,顯然當計算機推廣到世界以後隨着語種增多,這套編碼並不適用,因而中國針對中文推出了GB2312碼,可是多語言時,又不行了,因而就出現了強大的Unicode(萬國碼)。可是因爲Unicode存儲性能問題,在純英文時存儲效率要遠低於ACSII碼,因而又出現瞭如今的UTF-8編碼(8-bit Unicode Transformation Format),能夠看作是Unicode的增強版,經過可變長度的編碼來使存儲最優,並且UTF-8編碼包含了ASCII碼,這一點很是重要。
python處理文本時的中間編碼爲Unicode,因而就有了decode和encode,前者將unicode之外的字符串解碼爲unicode,後者將unicode編碼爲指定編碼。python
首先,當你在python代碼中輸入一個字符串時候,它是以什麼編碼形式被保存的呢?linux
1.若是輸入了一串純英文,數字,或英文狀態下的標點符號,那麼不管有沒有在代碼最前面作編碼申明(如"# -- coding:utf-8 --"),字符串都是由ASCII碼存儲的,緣由很簡單,ascii碼只支持英文,佔用性能與空間小。git
2.若是輸入了中文,那麼狀況一會兒就變得複雜起來。此時必須進行編碼申明,不然會拋出以下錯誤:「Non-ASCII character '\xe5' in file **,but no encoding declared」,意思就是你輸入了ASCII碼沒法識別的東西,且沒有進行編碼申明,因此此時要在文件開頭進行編碼申明,完整版以下:github
#!/usr/bin/python # -*- coding: <encoding name> -*-
此時
1.chardet庫的detect方法能夠獲得字符串的編碼類型,當輸入字符串爲unicode時程序報錯,有時候也會誤判,置信水平小魚0.7則不可輕信了。c#
2.上述只針對在非DOS中執行py文件時適用:若是是在IDLE中單步執行,則中文字符串是以系統默認編碼(windows-1252)保存;若是是在DOS界面中運行,則爲GBK編碼,並且中文也必須是GBK編碼纔可正常顯示,不然報錯。windows
3.選擇一款好的IDE,設置一款獨特的凸顯品味的字體與配色,可以讓初學者前期愉快地被編碼問題搞崩,而不是惱火地崩掉,也能幫助你很好的管理代碼。(推薦PyCharm,有免費版)函數
import sys reload(sys) sys.setdefaultencoding( "utf-8" )
以上代碼將系統編碼由ASCII碼轉爲UTF-8編碼。reload(sys)是由於import時將setdefaultencoding()方法刪除了,因此將其從新載入回來。爲何說ascii是系統默認編碼,由於當你使用str()給字符串encode或者是unicode()來decode時,都是默認使用了ASCII碼,所以常常會報出相似"UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 0"的錯誤,緣由就是字符串裏摻雜了中文,前面說到ascii碼是不支持中文的。若是把系統默認編碼設置爲utf-8,就不會出現這樣的問題了哦~
那麼,它與腳本開頭的"# -*- coding:utf-8 -*-"有什麼區別呢,注意,腳本開頭的編碼申明只是針對在腳本中輸入的非英文、數字、符號的字符串如中文,將其存成utf-8的形式,而非系統轉碼的形式。
當開頭設置默認編碼時,很容易出現程序運行到setdefaultencoding就默認終止的狀況(IDLE下),這時候須要在reload先後加入這個,目的是爲了從新定向,防止reload將變量重置:性能
stdout = sys.stdout reload(sys) sys.stdout = stdout
網頁抓取時遇到的主要問題,無非是網頁源代碼中摻雜了爲被轉義的編碼形式,被做爲純文本讀了進來,好比這樣一個字符串"\u6768\u777f",不管怎麼print 它都是這個形式由於它是文本,不是編碼,那麼怎麼轉爲中文呢,則須要用以下命令:字體
print text.decode('unicode_escape')
很是生動形象的,這句話至關因而把「逃離」掉的unicode編碼進行再編碼,因而就獲得了咱們想要的中文。
一樣,有的網頁中的文字是以反斜槓加三個數字形式呈現的,這個是標準的八進制字符串,如"\345\244\247",則表示一箇中文字;而utf-8的表現形式爲16進制字符串,像"\xe6\x9d\xa8"就表明着一個字 ,對於這些字符,只須要使用以下命令便可從文本轉爲編碼字符串:
print text.decode('string_escape')