上级给了一个文件夹,文件夹里有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)