使用Python語言做網絡爬蟲或者寫自動化腳本時,總會遇到“中文亂碼”的問題,很是頭疼。很多“中文亂碼”的問題是跟Python的解碼/編碼有關,是以今天和大家說說Python的解碼/編碼(以Python2.7為例)。
1.什麼是Python解碼/編碼?
Python裡面的解碼和編碼也就是unicode和str這兩種形式的互相轉化。解碼就是str -> unicode,相反的,編碼是unicode -> str。
總的來說就是:unicode是Python解釋器的内碼,所有代碼檔案在導入并執行時,Python解釋器會先将字元串使用你指定的編碼形式解碼成unicode,然後再進行各種操作。不管是對字元串的操作,還是正規表達式,還是讀寫檔案等等最好都通過unicode來進行。
Python解釋器在導入Python代碼檔案并執行時,會先檢視檔案頭有沒有編碼聲明(例如# -*- coding: utf-8 -*-等)。如果發現聲明,如# -*-coding: utf-8 -*-,會将檔案中的字元串從utf-8先解釋成unicode的形式;如果檔案頭沒有編碼聲明,則會以預設的ASCII來解釋成unicode的形式。
2.解碼函數decode()和編碼函數encode()
在Python中,解碼函數是decode(),編碼函數是encode()。
﹒decode()的作用是将其他編碼的字元串轉換成unicode 格式,例如:name.decode(“utf-8”),表示将utf-8編碼的字元串name轉換成unicode
﹒encode()的作用是将unicode編碼轉換成其他編碼的字元串,例如:
name.encode(“GB2312”),表示将GB2312編碼的字元串name轉換成GB2312
當代碼中同時有編碼聲明(例如# -*- coding: utf-8 -*-等)和編碼函數encode(‘gbk’),Python在執行時會優先選擇真實編碼gbk。當存在encode(‘gbk’)時,即便在開頭申明了#-*- coding: utf-8 -*-,沒有指定解碼方式,程式是會報錯的。
解決方案:在中文“哈哈”前加上字元“u”,直接使字元是unicode類型,不用再将“哈哈”去解碼操作。
注意:上圖中的 '\xb9\xfe\xb9\xfe'是“哈哈”的gbk編碼;'\xe5\x93\x88\xe5\x93\x88'是“哈哈”的utf-8編碼。上圖說明,當存在encode(‘gbk’)時,即便在開頭申明了#-*- coding: utf-8 -*-,在執行時會優先選擇encode()函數中的gbk編碼方式。
需要注意的一點是,假設stra=‘哈哈’,如果我們調用stra.encode(),這裡涉及到一個隐士的類型轉化,會先将stra轉化成unicode,才能進行編碼,這也是不太容易了解的地方。而在中文前添加“u”字元,就使得stra轉化成unicode這一步略去。
3.Python解碼
解碼是Python自動進行的,我們在程式開頭沒有編碼聲明(如:#-*-coding:utf-8-*-),也沒有指明解碼方式,Python就會使用sys.defaultencoding指明的方式來解碼。很多情況下sys.defaultencoding是ASCII。
4.Python編碼
Python預設采用ASCII編碼,而ASCII編碼不能用來編碼中文字元。舉個簡單的例子:
如下圖,運作腳本時會有提示。因為Python編碼預設是ASCII編碼,不支援中文。
解決方案1:在檔案開頭輸入支援中文的編碼方式:# -*- coding: gbk -*-。
解決方案2:Python2.x預設是不支援中文的,我們在程式的開頭加上#-*-coding:utf-8-*-,并在中文前加上“u”字元,也可以解決這個問題。這裡的“u”表示将後面跟的字元串以unicode格式存儲,然後Python會根據程式第一行的utf-8編碼識别代碼中的中文“你好”,然後轉換成unicode對象(重申一下:中文前加“u”,直接免去“将字元串解碼成unicode”這一步的操作哦)。
補充一點:如果在中文前沒有添加“u”,僅僅在程式的開頭加上#-*-coding:utf-8-*-,螢幕上列印出的不是“你好”,如下圖。這是由于Python編碼與控制台編碼的不一緻造成的。Windows下控制台中的編碼使用的是gbk,而在代碼中使用的utf-8,Python按照utf-8編碼列印到gbk編碼的控制台下自然就會不一緻而不能列印出正确的漢字。
總之,在Python2.x版本中使用中文,最好在程式開頭添加一行聲明檔案編碼的注釋:#-*-coding:utf-8-*-,然後在中文前添加“u”字元。可以不使用解碼、編碼函數,就盡量别使用(真的會繞暈的,哈哈……)。
原創文章,僅代表非比君個人觀點,說的不一定是對的,歡迎大家指正。
用微信添加 非比測試 公衆号即可訂閱。轉載請保留作者、公共賬号資訊,内容必須與本文保持嚴格一緻,不得修改/替換/增減本文包含的任何文字,不得擅自增加小标題、引語、摘要等。本公衆号一切内容禁止摘編、衍生及演繹。