Python 壓縮和解壓縮 zip 檔案 示範(含中文亂碼解決)

壓縮成 zip 檔案

使用 python 內建的 zipfile 將資料夾內的所有檔案歷遍加到壓縮檔:
    
import os
import zipfile


def zip_folder(folder_path, output_path):
    with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for root, dirs, files in os.walk(folder_path):
            for file in files:
                file_path = os.path.join(root, file)
                zipf.write(file_path, os.path.relpath(file_path, folder_path))
    

使用範例:
    
folder_path = 'C:/Users/ruyut/目標資料夾'
output_path = 'C:/Users/ruyut/壓縮檔.zip'

zip_folder(folder_path, output_path)
    

解壓縮

要解壓縮非常簡單:
    
import zipfile


def unzip_file(zip_path, extract_to='.'):
    """解壓縮 ZIP 檔案"""
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        zip_ref.extractall(extract_to)

    

使用範例:
    
zip_path = 'C:/Users/ruyut/壓縮檔.zip'
extract_to = 'C:/Users/ruyut/目的資料夾'

unzip_file(zip_path, extract_to)
    

會自動建立「目的資料夾」,並且中文資料夾和中文檔名都可以成功解壓縮,非常簡單,太棒了 Python!

解決中文亂碼問題

剛剛不是才說不會出現亂碼嗎?怎麼又會了? 因為一開始筆者是使用 WinRAR 這套軟體進行壓縮,沒有中文亂碼問題。但是後來筆者使用 Windows 11 內建的壓縮可就不是這樣了,現在在檔案總管中選擇檔案或資料夾 > 滑鼠右鍵點擊 > 「壓縮成 ZIP 檔案」壓縮完成後的 .zip 檔案使用剛剛的程式碼解壓縮後資料夾和檔案名稱中如果有中文就會變成亂碼,非常的頭痛。

經過一番研究後也不是不能解決,首先就是要先在命令提示字元(cmd)或是 PowerShell 中使用 chcp 指令,確認系統的編碼,筆者使用繁體中文,測出來是 950

經過反覆的嘗試終於找到一個解決的方式:
    
import os
import shutil
import zipfile


def unzip_file(zip_path, extract_to, encoding='big5'):
    """解壓縮含有中文檔案名稱的 ZIP 檔案"""
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        for file_info in zip_ref.infolist():

            try:
                file_name = file_info.filename.encode('cp437').decode(encoding)
            except UnicodeEncodeError:
                file_name = file_info.filename.encode(encoding, errors='ignore').decode(encoding, errors='ignore')

            extract_path = os.path.join(extract_to, file_name)

            if file_info.is_dir():
                os.makedirs(extract_path, exist_ok=True)
            else:
                os.makedirs(os.path.dirname(extract_path), exist_ok=True)
                with zip_ref.open(file_info.filename) as source, open(extract_path, 'wb') as target:
                    shutil.copyfileobj(source, target)
    

使用範例:
因為 950 是使用 big5 編碼,所以在 encoding 的地方放入 big5
    
zip_path = 'C:/Users/ruyut/壓縮檔.zip'
extract_to = 'C:/Users/ruyut/目的資料夾'

unzip_file(zip_path, extract_to, encoding='big5')
    

留言