「Python實用秘技01」復(fù)雜zip文件的解壓

添加微信號"CNFeffery"加入技術(shù)交流群
?本文完整示例代碼及文件已上傳至我的
?Github倉庫https://github.com/CNFeffery/PythonPracticalSkills
這是我的新系列文章「Python實用秘技」的第1期,本系列立足于筆者日常工作中使用Python輔助辦公的心得體會,每一期為大家?guī)硪粋€3分鐘即可學(xué)會的簡單小技巧。
作為系列第1期,我們即將學(xué)習(xí)的是:復(fù)雜zip文件的解壓。

廢話不多說,直接看問題,使用過Python中的標(biāo)準(zhǔn)庫zipfile解壓過zip格式壓縮包的朋友們,可能遇到過,當(dāng)壓縮文件中的目錄或文件名中包含中文等常見unicode字符時,典型如下面的例子:

使用zipfile的extract()或extractall()方法直接解壓時,產(chǎn)生的解壓結(jié)果名充斥著亂碼,這一點我們通過調(diào)用namelist()方法就可以看出來:
from?zipfile?import?ZipFile
#?讀入壓縮包文件
file?=?ZipFile('示例壓縮包.zip')
#?查看壓縮包內(nèi)目錄、文件名稱
file.namelist()

這是因為zipfile中針對壓縮包內(nèi)容的編碼兼容性差,但我們可以通過下面的函數(shù)自行矯正:
def?recode(raw:?str)?->?str:
????'''
????編碼修正
????'''
????
????try:
????????return?raw.encode('cp437').decode('gbk')
????
????except:
????????return?raw.encode('utf-8').decode('utf-8')
????
for?file_or_path?in?file.namelist():
????
????print(file_or_path,?'?------->?'?,?recode(file_or_path))

解決了文件名亂碼的問題后,接下來我們就可以配合shutil與os標(biāo)準(zhǔn)庫中的相關(guān)功能,實現(xiàn)將指定任意zip壓縮包,完好地解壓到指定的目錄中,代碼如下:
def?zip_extract_all(src_zip_file:?ZipFile,?target_path:?str)?->?None:
????
????#?遍歷壓縮包內(nèi)所有內(nèi)容
????for?file_or_path?in?file.namelist():
????????
????????#?若當(dāng)前節(jié)點是文件夾
????????if?file_or_path.endswith('/'):
????????????try:
????????????????#?基于當(dāng)前文件夾節(jié)點創(chuàng)建多層文件夾
????????????????os.makedirs(os.path.join(target_path,?recode(file_or_path)))
????????????except?FileExistsError:
????????????????#?若已存在則跳過創(chuàng)建過程
????????????????pass
????????
????????#?否則視作文件進行寫出
????????else:
????????????#?利用shutil.copyfileobj,從壓縮包io流中提取目標(biāo)文件內(nèi)容寫出到目標(biāo)路徑
????????????with?open(os.path.join(target_path,?recode(file_or_path)),?'wb')?as?z:
????????????????#?這里基于Zipfile.open()提取文件內(nèi)容時需要使用原始的亂碼文件名
????????????????shutil.copyfileobj(src_zip_file.open(file_or_path),?z)
????????????
#?向已存在的指定文件夾完整解壓當(dāng)前讀入的zip文件
zip_extract_all(file,?'解壓測試')
可以看到,效果完美??:

本期分享結(jié)束,咱們下回見~??

加入知識星球【我們談?wù)摂?shù)據(jù)科學(xué)】
400+小伙伴一起學(xué)習(xí)!
· 推薦閱讀?·
評論
圖片
表情
