1. 程式人生 > 實用技巧 >python解壓縮rar,zip檔案的正確姿勢

python解壓縮rar,zip檔案的正確姿勢

上級給了一個資料夾,資料夾裡有rar,zip型別的壓縮包,有的壓縮包還有密碼,有的壓縮包還有中文。要求把包裡的檔案全部解壓縮出來。以為簡單得很,碼的時候才發現,坑一堆呢。

一、對於rar檔案,僅pip install rarfile是不夠的,還需要pip install unrar。如果不想安裝unrar,把機器裡安裝的winrar資料夾中的unrar.exe檔案複製到python安裝路徑下的scripts資料夾中吧。

二、對於中文名的zip檔案,得認真得處理一下,不能直接呼叫extractall,你會發現出來的全是亂碼,需要獲取zip檔案的資訊,將檔名重新進行編碼。需要注意的是,有的中文名,zip檔案竟然是可以直接識別出來的。因此,在判斷的時候,多考慮一步。如下:

with zipfile.ZipFile(filename, 'r') as zf:
    for info in zf.infolist():
        try:
            newname=info.filename.encode('cp437').decode('gbk');
        except:
            try:#此處多進行了一次判斷
                newname=info.filename.encode('cp437').decode('utf-8');
            except:
                newname
=info.filename outname=newname.split('/') l=len(outname) if outname[l-1]!='':#判斷解壓出來的是否資料夾

三、沒有了,直接上程式碼吧。

import rarfile,zipfile,os,shutil
from pathlib import Path

basePath='d:/basePath'
outPath='d:/outPath'
passlist=[]
with open('pass.txt','r') as f:
    for line in f.readlines():
        passlist.append(line.rstrip())

for root,dirs,fs in os.walk(basePath): for f in fs: filename=os.path.join(root,f) type=os.path.splitext(filename)[-1][1:] if type=='rar': fileget=rarfile.RarFile(filename) with fileget as rf: if rf.needs_password():#判斷是否需要密碼 for pwds in passlist: try: fileget.extractall(outPath,pwd=pwds.encode())#不要直接用pwds,要編碼一下 print(filename+":"+pwds) except: pass else: fileget.extractall(outPath) elif type=='zip': with zipfile.ZipFile(filename, 'r') as zf: for info in zf.infolist(): try: newname=info.filename.encode('cp437').decode('gbk'); except: try: newname=info.filename.encode('cp437').decode('utf-8'); except: newname=info.filename outname=newname.split('/') l=len(outname) if outname[l-1]!='':#如果是檔案 if info.flag_bits & 0x01:#如果檔案有密碼 for pwd in passlist: try: body=zf.read(info,pwd=pwd.encode()) print("pass:"+pwd) with open(outPath+'/'+outname[l-1],'wb') as outfile: outfile.write(body) except: pass else: with open(outPath+'/'+outname[l-1],'wb') as outfile:#要把中文的zip解壓出中文,就不要用extract了,在新位置建立中文名檔案,然後把讀取出來的資料寫進去就可以。 outfile.write(zf.read(info)) else:#如果是檔案,直接複製到新位置 shutil.copy(filename,outPath+'\\'+f)