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)
  • 相关阅读:
    Spring Boot 结合 Redis 序列化配置的一些问题
    基于SpringBoot的代码在线运行的简单实现
    将Spring实战第5版中Spring HATEOAS部分代码迁移到Spring HATEOAS 1.0
    用Spring Security, JWT, Vue实现一个前后端分离无状态认证Demo
    使用最新AndroidStudio编写Android编程权威指南(第3版)中的代码会遇到的一些问题
    C# 内存管理优化畅想----前言
    C# 内存管理优化实践
    C# 内存管理优化畅想(三)---- 其他方法&结语
    C# 内存管理优化畅想(二)---- 巧用堆栈
    C# 内存管理优化畅想(一)---- 大对象堆(LOH)的压缩
  • 原文地址:https://www.cnblogs.com/ddddfpxx/p/13854720.html
Copyright © 2011-2022 走看看