zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    HDU 5213 分块 容斥
    HDU 2298 三分
    HDU 5144 三分
    HDU 5145 分块 莫队
    HDU 3938 并查集
    HDU 3926 并查集 图同构简单判断 STL
    POJ 2431 优先队列
    HDU 1811 拓扑排序 并查集
    HDU 2685 GCD推导
    HDU 4496 并查集 逆向思维
  • 原文地址:https://www.cnblogs.com/ddddfpxx/p/13854720.html
Copyright © 2011-2022 走看看