1. 程式人生 > >一次性解決你所有的編碼檢測問題

一次性解決你所有的編碼檢測問題

在日常使用中,我們難以避免會遇到編碼轉換問題。(如果編碼是什麼都不知道,請先看:什麼是編碼?

而進行編碼轉換的前提是你知道這個字串使用的是什麼編碼。

比如你使用 urllib.request.urlopen() 獲取一個網頁時,你特麼如果不知道網頁的編碼會怎樣?

直接 read().decode() 就可能會出現下邊錯誤:

這是因為無論是 encode() 還是 decode(),預設採取的編碼/解碼都是 encoding="utf-8" 編碼……

雖然你大 UTF-8 行跡踏遍天下,但在這神州大地,處處都有奇葩的好不?

這時候需要一個可靠的方式來檢測字串到底是什麼編碼,這樣我們才能對症下藥!

這裡我向大家推薦一個不錯的模組:chardet,使用它就可以檢測字串的編碼。

chardet 模組可以檢測以下編碼:
 

  • ASCII, UTF-8, UTF-16 (2 variants), UTF-32 (4 variants)
  • Big5, GB2312, EUC-TW, HZ-GB-2312, ISO-2022-CN (Traditional and Simplified Chinese)
  • EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP (Japanese)
  • EUC-KR, ISO-2022-KR (Korean)
  • KOI8-R, MacCyrillic, IBM855, IBM866, ISO-8859-5, windows-1251 (Cyrillic)
  • ISO-8859-2, windows-1250 (Hungarian)
  • ISO-8859-5, windows-1251 (Bulgarian)
  • windows-1252 (English)
  • ISO-8859-7, windows-1253 (Greek)
  • ISO-8859-8, windows-1255 (Visual and Logical Hebrew)
  • TIS-620 (Thai)

chardet 模組安裝方法:

1. (推薦)使用 pip 安裝,開啟命令列視窗(Windows 的 cmd,Linux 的 terminal,Mac 的“終端”)



輸入命令:pip install chardet

2. 下載安裝包並解壓:  chardet-3.0.4.zip 
開啟命令列視窗(同上),切換目錄到上方解壓包的資料夾,輸入命令:C:\Python34\python.exe setup.py install

chardet 模組用法:

非常簡單,使用該模組的 detect() 函式即可:

>>> import urllib.request
>>> response = urllib.request.urlopen("http://bbs.fishc.com").read()
>>> import chardet
>>> chardet.detect(response)
{'confidence': 0.99, 'encoding': 'GB2312'}

哦,confidence 是可信度的意思……

0.99 就是 99% 確定是 'GB2312'!

年輕人,你太傲嬌了,偶其實使用的是 GBK 編碼(GBK 是 GB2312 的擴充套件)

所以你直接 decode('GB2312') 還是會報錯的:(是不是很炸裂)

>>> response.decode("GB2312")
Traceback (most recent call last):
  File "<pyshell#41>", line 1, in <module>
    response.decode("GB2312")
UnicodeDecodeError: 'gb2312' codec can't decode byte 0xfd in position 22581: illegal multibyte sequence

你現在有兩種選擇:

一、忽略識別不出的字元(GB2312 支援的漢字比較少,如果用這種方法會出現小部分亂碼)

>>> response.decode("GB2312", "ignore")
……
<ul><li># <a href="thread-64400-1-1.html" title="喬布斯最精彩演講:這三個故事決定了我的一生" target="_blank">喬布斯最精彩演講:這三個故事決定了我的一</a></li><li># <a href="thread-50608-1-1.html" title="42個鍛鍊大腦的方法,你想不聰明都不行!" target="_blank">42個鍛鍊大腦的方法,你想不聰明都不行!</a></li><li># <a href="thread-23917-1-1.html" title="潘靠賜輳淚流滿面(轉)" target="_blank">潘靠賜輳淚流滿面(轉)</a>
……

二、(推薦)由於 GBK 是向下相容 GB2312,因此你檢測到是 GB2312,則直接用 GBK 來編碼/解碼

>>> if chardet.detect(response)['encoding'] == 'GB2312':
        response.decode('GBK')
……
<ul><li># <a href="thread-64400-1-1.html" title="喬布斯最精彩演講:這三個故事決定了我的一生" target="_blank">喬布斯最精彩演講:這三個故事決定了我的一</a></li><li># <a href="thread-50608-1-1.html" title="42個鍛鍊大腦的方法,你想不聰明都不行!" target="_blank">42個鍛鍊大腦的方法,你想不聰明都不行!</a></li><li># <a href="thread-23917-1-1.html" title="屌絲看完,淚流滿面(轉)" target="_blank">屌絲看完,淚流滿面(轉)
……