看透「0」、「1」邏輯,輕鬆解決Python中文亂碼

Python中關於「中文亂碼」的問題,現規整以下,並統一回答python

同窗問:
jacky:我在爬取XX網站信息的時候,中文怎麼老是顯示的亂碼?
jacky:UTF-8與GBK究竟是個啥?
jacky:我用的是Mac系統,網上說Python3中默認的編碼是UTF-8,可我顯示中文時怎麼仍是亂碼?數據庫

(一)邏輯導圖

Created with Raphaël 2.1.0 Python中爲何會出現亂碼? 解碼與編碼方式不一致 解碼與編碼具體方式有哪些? 實質是什麼? Python亂碼問題總結

(二)基礎鋪墊

1.計算機的底層邏輯

Created with Raphaël 2.1.0 生活、交易、娛樂、科學研究,都離不開計算機(廣義)。 無所不能的計算機是怎樣實現其功能的? 經過計算機語言編碼實現的(Python就是其中之一)。 那麼語言編碼又是怎樣構成的? 計算機語言是由字母,字符和數字組合而成的, 不一樣的排列組合,構成了不一樣的語言要素, 其排列組合的規則就是編碼語言的語法 接下來,咱們要探討,這些規則是如何制定的? 水印:@數據分析-jacky 經過0和1的不一樣組合, 若干個0和1,若干種組合,咱們制定了編碼語言的不一樣規則 爲何只是0和1的組合? 這裏的0和1,也只是輔助咱們標記計算機規則的 標記的是什麼?標記電路最底層的兩種狀態:通電和不通電 標記電路最底層的兩種狀態:通電和不通電 計算機底層就是電路,現階段,人類處理電路可能的辦法只能是讓它通電,或不通電。 人類是多麼的偉大 僅用0和1,就構建了咱們如今這個機器智能的世界

2.字符編碼

計算機只認二進制的「0」和「1」svg

ASCII

  • 這個世界的規則就是誰發起,誰定規則。計算機是美國人發明的,在開發計算機的時候,美國人只考慮到了英文的兼容性,並無考慮包括中文在內的其餘語言。函數

  • 英語構成計算機最底層的元素就是:26個英語字母,加上特殊字符,加上數字。網站

(1)發明計算機時,字符編碼使用的是ascii碼,包括Python2默認的字符編碼就是ascii碼(Python3默認使用的是UTF-8,詳見下文);編碼

(2)ascii碼爲1字節(8位)url

  • 8位二進制(例如:01010101)有多少種排列組合? 28 =256種可能spa

  • 對於英文來講,8位二進制足夠用了,全部python2還默認ascii碼也不足爲奇。code

Unicode(萬國碼)

  • 全球化和科技共享,讓計算機的開發者認識到,要開發一種各國語言都能兼容的編碼,就有了unicode,也叫萬國碼。

(1)unicode 包含各國全部的語言文件和符號,對於中文來講,8位已經不夠用了,unicode規定:一箇中文漢字最少用3個字節來表示。orm

  • 一個字節是8位,1byte=8bit=01010101,一個漢字最少有2的24次方種組合

(2)Python中能夠用bin函數將十進制轉化爲二進制

bin(82)
'0b1010010'  #b表示的R是二進制

@數據分析-jacky

(3)萬國碼的弊端

  • 佔內存和硬盤

    • 用英文字母R舉例:如何用ascii碼錶示爲’0b1010010’,如何用萬國碼表示爲
      ‘000000000b1010010’,由於萬國碼,最少是2個字節,與ascii相比,萬國碼白白浪費了1個字節的空間。
  • 針對unicode的弊端,現在的開發者,又對unicode進行了精簡,開發了UTF-8編碼

(4)特別說明(讀完下文在回來看,就好理解了)

  • Unicode是Python的內部編碼,也是編碼和解碼的中間編碼。

UTF-8編碼

  • UTF-8編碼是對unicode 的一個再加工
    • 對unicode 的編碼進行了劃分和整理,用8位的就劃分爲用8位的,不額外在用空間
  • 規則:
    • 英文:8位
    • 歐洲:16位
    • 中文:24位
  • 特別說明:在Unicode編碼方式下,才存在 utf-8,utf-16,utf-32的編碼方式,這句話對於解釋下文的解碼與編碼特別重要

GBK編碼

UTF-8 GBK(@數據分析-jacky)
外國人開發 中國人開發
外國人看不會亂碼 外國人看會亂碼
一個漢字佔3個字節 一個漢字佔2個字節

(三)編碼與解碼

一、基礎內容

編碼:將字符轉化爲二進制字節的過程
解碼:將二進制字節轉化爲字符的過程

Created with Raphaël 2.1.0 字符 字符 二進制字節 二進制字節 編碼(字符轉化爲字節的過程) 可逆過程 解碼
Created with Raphaël 2.1.0 UTF-8|GBK UTF-8|GBK Unicode中間編碼 Unicode中間編碼 encode 編碼 可逆 decode 解碼

二、解碼和編碼的實現方法

(1) 基本邏輯

字符串在Python內部的表示是Unicode編碼。
所以在作編碼轉換時,一般須要以Unicode做爲中間編碼,即先將其餘編碼的字符串解碼(decode)成Unicode,再從Unicode編碼(encode)成另外一種編碼。

(2) encode與decode

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也會報錯

(3)支持字符串類型的兩種數據模型

python編碼有兩種數據模型來支持字符串類型 :

  • 一種是str ;
  • 一種是unicode

(四)解決Python亂碼的思路

Created with Raphaël 2.1.0 亂碼? Unicode中轉碼 咱們須要的編碼方式

代碼的實現方式:

decode()->unicode->encode轉化爲須要的格式

實戰案例:

content爲從文件中讀取的gbk編碼的內容,咱們經過以上方法輸出該內容。

content.decode('gbk').encode('utf-8')
  • decode方法將content內容轉爲unicode格式
  • encode方法將unicode格式的數據轉化爲本身所須要的編碼方式。

(五)數據科學領域需注意的問題

做爲數據分析(挖掘)師,python與數據庫的關聯是最多見的,咱們用python鏈接數據庫後,將數據寫到數據庫裏的中文有時會是亂碼

解決辦法是在python文件中加上這樣幾句話:

conn.set_character_set('utf8')
cur.execute('SET CHARACTER SET utf8')
cur.execute('SET character_set_connection=utf8')
  • conn是數據庫的connection,cur是connection的光標cursor
相關文章
相關標籤/搜索