1. 程式人生 > >python使用zipfile解壓中文亂碼問題

python使用zipfile解壓中文亂碼問題

 

 

 

 

 

 

 

在zipfile.ZipFile中獲得的filename有中日文則很大可能是亂碼,這是因為

在zip標準中,對檔名的 encoding 用的不是 unicode,而可能是各種軟體根據系統的預設字符集來採用(此為猜測),而zipfile中根據檔案 flag 檢測的時候,只支援 cp437 和 utf-8。

具體zipfile模組中的原始碼如下
if flags & 0x800:
# UTF-8 file names extension
filename = filename.decode('utf-8')
else:
# Historical ZIP filename encoding
filename = filename.decode('cp437')
可見編碼被正確識別為utf8時的情況外,都會被識別並decode為cp437編碼,但如果實際是gbk等其他編碼時就變為亂碼了。所以解決的方法在於被decode為cp437後重新再手動轉為正確的編碼。

在實際過程中可以對已經先用zipfile進行解壓,然後對unzip資料夾中的亂碼檔案直接進行重新命名。具體實現過程如下:

import os


def an_garcode(dir_names):
    """anti garbled code"""
    os.chdir(dir_names)


    for temp_name in os.listdir('.'):
        try:
            #使用cp437對檔名進行解碼還原
            new_name = temp_name.encode('cp437')
            #win下一般使用的是gbk編碼
            new_name = new_name.decode("gbk")
            #對亂碼的檔名及資料夾名進行重新命名
            os.rename(temp_name, new_name)
            #傳回重新編碼的檔名給原檔名
            temp_name = new_name
        except:
            #如果已被正確識別為utf8編碼時則不需再編碼
            pass


        if os.path.isdir(temp_name):
            #對子資料夾進行遞迴呼叫
            an_garcode(temp_name)
            #記得返回上級目錄
            os.chdir('..')


an_garcode(os.getcwd())
---------------------

直接上最後成功程式碼,使用cp437可以正確讀取部分,但是還有一部分卻打印出來\u的編碼,

因為看了alex的文章,又在catch中加上了utf-8的解碼方式

#-*- coding: utf-8 -*-
import zipfile

# 預設模式r,讀
azip = zipfile.ZipFile("/Users/a/my_file/feise.zip", 'r')
# 返回所有資料夾和檔案
zip_list = azip.namelist()
for zip_file in zip_list:
print(zip_file)
print(zip_file.encode('utf-8'))
try:
zip_file = zip_file.encode('cp437').decode('gbk')
except:
zip_file = zip_file.encode('utf-8').decode('utf-8')
print(zip_file)

  一句話,就是轉換成unicode,壓縮前是什麼編碼,使用什麼編碼encode再decode回gbk、utf-8

一句話,就是轉換成unicode,壓縮前是什麼編碼,使用什麼編碼encode再decode回來

先看測試程式碼:

1 2 3 4 5 6 7 8 9 10 #-*- coding: utf-8 -*- import  zipfile   # 預設模式r,讀 azip  =  zipfile.ZipFile( "/Users/a/my_file/feise.zip" 'r' ) # 返回所有資料夾和檔案 zip_list  =  azip.namelist() for  zip_file  in  zip_list:      print (zip_file)      print (zip_file.encode( 'utf-8' ))