Python版本:3.9.6
ide:PyCharm 2021.1.3
常用的压缩格式有很多种,而不同的压缩包的解压需要用到不同的库,下面根据一些常用的压缩包给出各自的解决方案。
目录
rar格式
zip格式
完整源码
主要代码就两行,如下:
import rarfile
rar = 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 rarfile
rar = 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、也是最主要的原因,它快呀,快的不是一点半点。
完整代码在最后!!!
主要代码如下:
import zipfile
zip = zipfile.ZipFile(file)
zip.extractall(outdir)
zip.close()
这几行代码可以满足我们的解压缩功能,但是解压后的子文件夹或文件如果存在中文名,会被解成乱码而不可读,通过查各种资料,发现没有特别好的办法来解决这个问题,主要也是有两种方式:
1、直接修改三方库zipfile的源码
参考:python3 zipfile解压文件 出现文件名为乱码解决方案!!!!
2、先解压缩,之后再递归重命名
参考:python3 zipfile解压中文乱码问题解决
虽然说第一种方式改起来比较快,但是涉及到修改第三方库,笔者不建议这么玩。我个人也是基于第二种方式进行了调整,使得程序尽量兼容。
递归重命名函数封装如下:
import os
def 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 zipfile
class 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):
break
def 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):
pass
else:
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()