一次性解決你所有的編碼檢測問題
在日常使用中,我們難以避免會遇到編碼轉換問題。(如果編碼是什麼都不知道,請先看:什麼是編碼?)
而進行編碼轉換的前提是你知道這個字串使用的是什麼編碼。
比如你使用 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">屌絲看完,淚流滿面(轉)
……