Python中關於「中文亂碼」的問題,現規整以下,並統一回答python
同窗問:
jacky:我在爬取XX網站信息的時候,中文怎麼老是顯示的亂碼?
jacky:UTF-8與GBK究竟是個啥?
jacky:我用的是Mac系統,網上說Python3中默認的編碼是UTF-8,可我顯示中文時怎麼仍是亂碼?數據庫
計算機只認二進制的「0」和「1」svg
這個世界的規則就是誰發起,誰定規則。計算機是美國人發明的,在開發計算機的時候,美國人只考慮到了英文的兼容性,並無考慮包括中文在內的其餘語言。函數
英語構成計算機最底層的元素就是:26個英語字母,加上特殊字符,加上數字。網站
(1)發明計算機時,字符編碼使用的是ascii碼,包括Python2默認的字符編碼就是ascii碼(Python3默認使用的是UTF-8,詳見下文);編碼
(2)ascii碼爲1字節(8位)url
8位二進制(例如:01010101)有多少種排列組合?
對於英文來講,8位二進制足夠用了,全部python2還默認ascii碼也不足爲奇。code
- 全球化和科技共享,讓計算機的開發者認識到,要開發一種各國語言都能兼容的編碼,就有了unicode,也叫萬國碼。
(1)unicode 包含各國全部的語言文件和符號,對於中文來講,8位已經不夠用了,unicode規定:一箇中文漢字最少用3個字節來表示。orm
(2)Python中能夠用bin函數將十進制轉化爲二進制
bin(82)
'0b1010010' #b表示的R是二進制
(3)萬國碼的弊端
佔內存和硬盤
針對unicode的弊端,現在的開發者,又對unicode進行了精簡,開發了UTF-8編碼
(4)特別說明(讀完下文在回來看,就好理解了)
- UTF-8編碼是對unicode 的一個再加工
- 對unicode 的編碼進行了劃分和整理,用8位的就劃分爲用8位的,不額外在用空間
- 規則:
- 英文:8位
- 歐洲:16位
- 中文:24位
- 特別說明:在Unicode編碼方式下,才存在 utf-8,utf-16,utf-32的編碼方式,這句話對於解釋下文的解碼與編碼特別重要
UTF-8 | GBK(@數據分析-jacky) |
---|---|
外國人開發 | 中國人開發 |
外國人看不會亂碼 | 外國人看會亂碼 |
一個漢字佔3個字節 | 一個漢字佔2個字節 |
編碼:將字符轉化爲二進制字節的過程
解碼:將二進制字節轉化爲字符的過程
字符串在Python內部的表示是Unicode編碼。
所以在作編碼轉換時,一般須要以Unicode做爲中間編碼,即先將其餘編碼的字符串解碼(decode)成Unicode,再從Unicode編碼(encode)成另外一種編碼。
decode的做用是將其餘編碼的字符串轉換成Unicode編碼,如str1.decode(‘gbk’),表示將gbk編碼的字符串str1轉換成Unicode編碼;
encode的做用是將Unicode編碼轉換成其餘編碼的字符串,如str2.encode(‘UTF-8’),表示將Unicode編碼的字符串str2轉換成UTF-8編碼所以,使用Python轉碼的時候必定要先搞明白,字符串str是什麼編碼,而後decode成Unicode,而後再encode成其餘編碼。
特別注意:
若是一個字符串已是unicode了,再進行解碼則將出錯,所以一般要對其編碼方式是否爲unicode進行判斷:
用非unicode編碼形式的string來encode也會報錯
python編碼有兩種數據模型來支持字符串類型 :
- 一種是str ;
- 一種是unicode
代碼的實現方式:
decode()->unicode->encode轉化爲須要的格式
實戰案例:
content爲從文件中讀取的gbk編碼的內容,咱們經過以上方法輸出該內容。
content.decode('gbk').encode('utf-8')
做爲數據分析(挖掘)師,python與數據庫的關聯是最多見的,咱們用python鏈接數據庫後,將數據寫到數據庫裏的中文有時會是亂碼
解決辦法是在python文件中加上這樣幾句話:
conn.set_character_set('utf8')
cur.execute('SET CHARACTER SET utf8')
cur.execute('SET character_set_connection=utf8')