讀取時出現 UnicodeDecodeError
pd.read_csv 預設用 UTF-8 讀取。如果檔案是用 Big5 儲存的(例如 Excel 另存的「CSV(逗號分隔)」、銀行對帳單或政府開放資料的舊檔案),就會出現 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa4,而 A4 A4 正是 Big5 的「中」。這時指定編碼即可:
pd.read_csv('data.csv', encoding='cp950'):Windows 實際使用的 Big5,比 Python 的big5多收錄「碁」「銹」「裏」等字,比較不容易出錯。- 香港的檔案用
encoding='big5hkscs',才讀得到「嘅」「咗」等粵語用字。 - 檔案開頭有 BOM 時用
encoding='utf-8-sig',否則第一個欄位名稱前會多出一個看不見的\ufeff,用欄位名稱取值時出現KeyError。 - 不知道是什麼編碼?把檔案拖進 Mojibuster,它會自動辨識編碼,並儲存成 UTF-8。
'cp950' codec can't decode:open() 的預設編碼
反過來的錯誤也很常見:open('data.txt') 沒寫 encoding 時,Python 在 Windows 上使用系統編碼,繁體中文 Windows 上就是 cp950。讀取 UTF-8 檔案時會出現 UnicodeDecodeError: 'cp950' codec can't decode byte …。所以請一律寫上 encoding='utf-8',或設定環境變數 PYTHONUTF8=1。根據 PEP 686,之後的 Python 版本會預設使用 UTF-8。
別用 latin-1 硬讀 Big5
為了讓錯誤訊息消失,網路上常有人建議 encoding='latin-1'。它永遠不會出錯,但 Big5 的中文會變成 ³¯¤j¤å 這類符號,存檔後就整份變成亂碼。好在位元組都還在:把這樣的檔案拖到上方的框中,Mojibuster 會還原成中文。
亂碼
©m¦W,«°¥«,ª÷ÃB ³¯¤j¤å,¥x¥_,1250 ªL¤p¬ü,°ª¶¯,980
修復後
姓名,城市,金額 陳大文,台北,1250 林小美,高雄,980
to_csv:用 Excel 開啟是亂碼
df.to_csv('export.csv') 寫出的是不含 BOM 的 UTF-8。繁體中文版 Excel 按兩下開啟時會用 Big5 讀取,中文就成了亂碼。改用 encoding='utf-8-sig' 寫出含 BOM 的檔案,Excel 就能辨識 UTF-8。詳見 Excel 開啟 CSV 亂碼。
requests 爬蟲中文亂碼
requests 依照回應標頭 Content-Type 決定 response.text 的編碼。如果文字回應的標頭沒寫字元集,它會用 ISO-8859-1 解碼:UTF-8 網頁變成 ä½ å¥½,Big5 網頁變成 §A¦n。先設定 response.encoding = response.apparent_encoding(或直接寫 'utf-8'、'cp950'),再讀取 response.text。
如果讀寫時用過 errors='replace' 或 encoding_errors='replace',無法轉換的字已經變成 ? 或 �,原本的資訊遺失了,無法還原。更多亂碼類型請見 亂碼是什麼。
常見問題
big5 和 cp950 該用哪個?
讀取 Windows 產生的檔案時用 cp950,它包含 Big5 的全部字元,還多了一些常用字和符號。香港的檔案用 big5hkscs。
有修復亂碼的 Python 套件嗎?
有,例如 ftfy,不過它主要針對西文亂碼。處理單一檔案又不想寫程式時,用 Mojibuster 比較快,儲存前還能看到每一處變更。
分隔符號和數字會被改動嗎?
不會。Mojibuster 只修改亂碼的字元,逗號、引號和換行都保持原樣。