python解压缩-[rar]、[zip]

Python版本:3.9.6

ide:PyCharm 2021.1.3


        常用的压缩格式有很多种,而不同的压缩包的解压需要用到不同的库,下面根据一些常用的压缩包给出各自的解决方案。


目录

rar格式

zip格式

完整源码


rar格式

        主要代码就两行,如下:

import rarfile

rar = rarfile.RarFile(file)
# 解压缩到指定目录
rar.extractall(outdir)

        但是执行时大多数人会报错:rarfile.RarCannotExec: Cannot find working tool,如下:

        看上去像是少了什么东西,我们再来看看这个库的说明,发现必须要配合unrar的工具来使用。

python解压缩-[rar]、[zip]_第1张图片

        通过网上找方法,基本都是以下两种:

        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、也是最主要的原因,它快呀,快的不是一点半点。

        完整代码在最后!!!


zip格式

        主要代码如下:

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()

你可能感兴趣的:(python,python,pycharm)