最近在嘗試微軟最近推出的 MarkItDown 工具,它使用 Python 開發,可用於將各種文件檔案轉換為 Markdown 格式,支援的文件格式也非常多,這在 AI 盛行的時代是非常有用的。因為文件換為 Markdown 格式之後,可以讓大語言模型進行分析。不過我在 PowerShell 底下使用的時候,沒有意外的又出意外了,因為它無法正確的處理 UTF-8 字元的輸入輸出,所以只要遇到中文就掛掉,真的很煩,這種問題都不知道處理幾次了。這篇文章我打算來介紹如何讓 Python 程式正確的處理 UTF-8 字元。
問題重現
首先我們來看看問題是如何重現的,我們可以使用下面的程式碼來重現問題:
markitdown coding-guideline.pdf > coding-guideline.md
錯誤訊息如下:
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\Python312\Scripts\markitdown.exe\__main__.py", line 7, in <module>
File "C:\Python312\Lib\site-packages\markitdown\__main__.py", line 39, in main
print(result.text_content)
UnicodeEncodeError: 'cp950' codec can't encode character '\u26ab' in position 4123: illegal multibyte sequence
解決這個問題,最簡單的方法是改用 -o filename
參數來指定輸出檔案,這樣就不會有問題了:
markitdown coding-guideline.pdf -o coding-guideline.md
但我有不得不用 Pipe (|
) 的理由,所以這個問題我必須解決!✊
解決方法 1:透過 PYTHONUTF8
環境變數
解決方法也很簡單,給個環境變數就好:
-
命令提示字元 (Command Prompt)
set PYTHONUTF8=1
set PYTHONIOENCODING=utf-8
-
PowerShell
$env:PYTHONUTF8=1
$env:PYTHONIOENCODING='utf-8'
-
Shell
export PYTHONUTF8=1
export PYTHONIOENCODING=utf-8
這樣就可以正確的處理 UTF-8 字元了,以下這段命令可以正常執行!👍
markitdown coding-guideline.pdf > coding-guideline.md
至於 PYTHONIOENCODING
跟 PYTHONUTF8
環境變數的區別如下:
-
PYTHONUTF8
從 Python 3.7
開始,引入了 PYTHONUTF8
環境變數。當您將 PYTHONUTF8
設定為 1
時,Python 會啟用 UTF-8
模式,這意味著 Python 會在多數情況下預設使用 UTF-8
編碼,包括檔案處理、標準輸入輸出(STDIN
, STDOUT
)和管道(pipes)等。這有助於在不同的作業系統和地區設定中保持一致的編碼行為,減少因預設編碼不同而導致的問題。
-
PYTHONIOENCODING
此環境變數用於指定 Python 在執行期間對標準輸入 (stdin
)、標準輸出 (stdout
) 和標準錯誤 (stderr
) 的編碼方式。當您設定 PYTHONIOENCODING
為 utf-8
時,Python 會使用 UTF-8 編碼來處理這些標準流 (STDIN
, STDOUT
, STDERR
),這對於需要處理多語言文字的應用程式特別有用。需要注意的是,這僅影響標準輸入和輸出,對於使用 open()
函數讀寫檔案時的編碼,仍需在程式碼中明確指定 encoding
參數。
這意味著,當你使用的 Python 版本在 Python 3.7 以上時,你可以使用 PYTHONUTF8
環境變數來啟用 UTF-8 模式就好,設定 PYTHONIOENCODING
就顯得有點多餘。
使用建議如下:
需要注意的是,目前 Python 最新版為 Python 3.13.1
,而預計從 Python 3.15
開始,將預設啟用 UTF-8
模式,這意味著未來版本的 Python 將自動使用 UTF-8 作為預設編碼。這對於處理 UTF-8 字元的問題,將會是一個很大的改進!🎉
解決方法 2:透過 -X utf8
參數
第二種解決方法,則是靠 python
指令的 -X utf8
參數來指定編碼,這樣也確實可以解決問題!
python -X utf8 -m markitdown
相關連結