Python版本:3.9.6
ide:PyCharm 2021.1.3
常用的压缩格式有很多种,而不同的压缩包的解压需要用到不同的库,下面根据一些常用的压缩包给出各自的解决方案。
目录
rar格式
zip格式
完整源码
rar格式
主要代码就两行,如下:
import rarfilerar = rarfile.RarFile(file)
# 解压缩到指定目录
rar.extractall(outdir)
但是执行时大多数人会报错:rarfile.RarCannotExec: Cannot find working tool,如下:
看上去像是少了什么东西,我们再来看看这个库的说明,发现必须要配合unrar的工具来使用。
通过网上找方法,基本都是以下两种:
1、下载WinRAR工具,将UnRAR.exe放在脚本目录venv/Scripts下,因为rarfile识别的是unrar.exe,需要改下名称
2、系统环境变量Path中加入unrar.exe所在目录(注意是系统变量,不是用户变量)。
笔者测试了两种方法,第一种方法没有作用,第二种方法是有用的,说明无论如何都要配置环境变量(如果使用pychram,注意修改之后重启pychram端)。
同时,笔者发现了另外一个unrar库,使用方式同rarfile,如下:
from unrar import rarfilerar = rarfile.RarFile(file)
# 解压缩到指定目录
rar.extractall(outdir)
但是执行时报错:LookupError: Couldn't find path to unrar library.,如下:
这是因为缺少了依赖的rar的官方库文件,只需下载库文件,配置环境变量即可,步骤如下:
1、先到RARLab官方下载库文件,http://www.rarlab.com/rar/UnRARDLL.exe ,默认路径安装;
2、添加环境变量,在系统变量中新建, 变量名输入UNRAR_LIB_PATH ,变量值如果是64位系统,就输入 C:\Program Files (x86)\UnrarDLL\x64\UnRAR64.dll,如果是32位系统就输入 C:\Program Files (x86)\UnrarDLL\UnRAR.dll
3、重启pychram再运行代码
参考:解决Python下安装unrar后仍然提示Couldn't find path to unrar library...
两个库都可以实现rar格式解压缩的目的,但是笔者推荐使用 from unrar import rarfile ,原因主要有两个:
1、import rarfile 需要下载一个WinRAR来获取UnRaR.exe,对于使用其他压缩工具的朋友不友好;
2、也是最主要的原因,它快呀,快的不是一点半点。
完整代码在最后!!!
zip格式
主要代码如下:
import zipfilezip = zipfile.ZipFile(file)
zip.extractall(outdir)
zip.close()
这几行代码可以满足我们的解压缩功能,但是解压后的子文件夹或文件如果存在中文名,会被解成乱码而不可读,通过查各种资料,发现没有特别好的办法来解决这个问题,主要也是有两种方式:
1、直接修改三方库zipfile的源码
参考:python3 zipfile解压文件 出现文件名为乱码解决方案!!!!
2、先解压缩,之后再递归重命名
参考:python3 zipfile解压中文乱码问题解决
虽然说第一种方式改起来比较快,但是涉及到修改第三方库,笔者不建议这么玩。我个人也是基于第二种方式进行了调整,使得程序尽量兼容。
递归重命名函数封装如下:
import osdef rename(curr_dir):"""重命名文件夹或文件名:param curr_dir: 目录:return:"""os.chdir(curr_dir)for name in os.listdir():# 使用cp437对文件名进行解码还原后转为可读格式new_name = name.encode('cp437').decode('gbk')os.rename(name, new_name)# 递归调用if os.path.isdir(new_name):self.rename(new_name)# 处理完要回到上级目录os.chdir('..')
以上代码需要注意一点,使用chdir更改了工作目录,如果后面还需要使用open()函数,需要切换工作目录,否则会找不到对应的文件,因为open()只检查当前工作目录,不遍历系统路径查找文件。
完整源码
"""
function: 批量解压缩
detail: 批量解压缩
author: w.royee
date: 2021-08-29
"""import os
# import rarfile
import shutil
from unrar import rarfile
import zipfileclass Uncompress:def __init__(self):self.abs_path = os.getcwd() # 工作目录的绝对路径self.compress_path = os.path.join(self.abs_path, '压缩包目录')self.umcompress_path = os.path.join(self.abs_path, '解压缩目录')# walk出来的结果是递归的目录结构,demo只处理当前目录下的文件,不处理子文件夹下的文件,因此取结果中的第一条for path_, dir_, self.filenames in os.walk(self.compress_path):breakdef unrar(self):"""rar格式解压缩:param:return:"""for filename in self.filenames:name, ext = os.path.splitext(filename)if '.rar' == ext:print('解压缩文件:', filename)file = os.path.join(self.compress_path, filename)rar = rarfile.RarFile(file)# 设置解压缩指定目录outdir = os.path.join(self.umcompress_path, name)if os.path.isdir(outdir):passelse:os.makedirs(outdir)# 解压缩到指定目录rar.extractall(outdir)def unzip(self):"""zip格式解压缩:param:return:"""for filename in self.filenames:file = os.path.join(self.compress_path, filename)# 重新定位到工作目录,否则ZipFile实现使用open找不到源文件os.chdir(self.compress_path)# 判断是否zip压缩格式if zipfile.is_zipfile(filename):print('解压缩文件:', filename)# 设置解压缩指定目录outdir = os.path.join(self.umcompress_path, os.path.splitext(filename)[0])# 解压目录如果存在,先递归删除,重新创建,否则重复运行程序rename会存在同名文件报错if os.path.exists(outdir):shutil.rmtree(outdir)os.makedirs(outdir)# 解压缩到指定目录zip = zipfile.ZipFile(file)zip.extractall(outdir)zip.close()# 解压后重命名文件,修复中文乱码self.rename(outdir)def rename(self, curr_dir):"""重命名文件夹或文件名:param curr_dir: 目录:return:"""os.chdir(curr_dir)for name in os.listdir():# 使用cp437对文件名进行解码还原后转为可读格式new_name = name.encode('cp437').decode('gbk')os.rename(name, new_name)# 递归调用if os.path.isdir(new_name):self.rename(new_name)# 处理完要回到上级目录os.chdir('..')if __name__ == '__main__':Uncompress = Uncompress()# print('包括压缩包如下:')# for each in Uncompress.filenames:# print(each)# input('输入回车开始解压缩')Uncompress.unrar()Uncompress.unzip()