[Python] 自动化办公 监测下载压缩包自动解压并删除原始包

转载请注明:陈熹 chenx6542@foxmail.com (简书号:半为花间酒)
若公众号内转载请联系公众号:早起Python

本例可以学到的知识点:

  1. os 模块综合应用
  2. glob 模块综合应用
  3. 利用 gzip zipfile rarfile tarfile 模块解压文件

一、需求描述:

编写一个Python程序,每次下载压缩包形式的文件后,自动将内部文件解压到当前文件夹后将压缩包删除

二、步骤分析和前置知识:

码代码之前需要将复杂问题解释成多个明确的要求,即这个程序实现的逻辑为:

  1. 定时检测某个文件夹(如 download 文件夹)是否存在压缩文件
  2. 如果有新出现的压缩文件则将其解压到当前文件夹内的新文件夹中
  3. 删除压缩文件

提到压缩文件就要分不同压缩格式进行讨论,主要有以下4种:

  1. .gz: 即gzip,通常只能压缩一个文件
  2. .tar: 本质上不是压缩工具而是打包工具,可以跟.gz配合形成.tar.gz的打包压缩格式
  3. .zip: 和.tar.gz很类似但可以打包压缩多个文件
  4. .rar: 打包压缩文件,最初用于DOS

因此,文件是否为压缩文件的判断逻辑可以如下:

  1. 建立一个含压缩包后缀的列表
    compressed_lst = ['gz', 'tar', 'zip', 'rar']
  2. 目标文件夹下的所有文件名运行filename.split(.)[-1]获取后缀名
  3. 判断后缀名是否在compressed_lst中,如果存在则运行后续的解压代码
  4. 如果是以gz结尾的文件,解压后需要再次判断是否是以.tar结尾,并进行相应处理

不同压缩文件的解压代码各不相同,在后续代码操作中具体展开

三、代码实现

获取 download 文件夹下所有文件的文件名

import glob
import os

path = r'C:\xxxx\download'
file_lst = glob.glob(path + '/*')
# 列表推导式
filename_lst = [os.path.basename(i) for i in file_lst]

print(filename_lst)

根据文件的后缀名判断是否需要压缩

先看一下代码框架

for i in filename_lst:
    if '.' in i:
        # 获取后缀名
        suffix = i.split('.')[-1]
        # 逐个将后缀名和各格式的压缩后缀匹配
        if suffix == 'gz':
            pass
            if ...: # 再次判断新产生的文件名是否以 .tar 结尾
                pass
        if suffix == 'tar':
            pass
        if suffix == 'zip':
            pass
        if suffix == 'rar':
            pass

有2个注意点:

  1. 有些文件没有后缀名,因此可能不存在 .,这时用 filename.split('.')[-1] 会报错,因此需要先判断
  2. .gz 结尾的文件,解压后需要再次判断是否是以 .tar 结尾

然后我们就可以分别将四种压缩文件的解压代码写成函数,符合时候单独调用即可

  • .gz 文件
import gzip

def ungz(filename):
    filename = filename[:-3] # gz文件的单文件解压就是去掉 filename 后面的 .gz
    gz_file = gzip.GzipFile(filename)
    with open(filename, "w+") as file:
        file.write(gz_file.read())
        return filename  # 这个gzip的函数需要返回值以进一步配合untar函数

前面反复提及的gz文件有可能跟tar文件配合,因此解压gz文件后需要再判断是否有必要解开tar文件
这里就可以先把tar文件的函数写出来

  • .tar 文件
import tarfile

def untar(filename):
    tar = tarfile.open(filename)
    names = tar.getnames()
    # tar本身是将文件打包,解除打包会产生很多文件,因此需要建立文件夹存放
    if not os.path.isdir(filename + "_dir"):
        os.mkdir(filename + "_dir")
    for name in names:
        tar.extract(name, filename + "_dir/")
    tar.close()
  • .zip 文件
import zipfile

def unzip(filename):
    zip_file = zipfile.ZipFile(filename)
    # 类似tar解除打包,建立文件夹存放解压的多个文件
    if not os.path.isdir(filename + "_dir"):
        os.mkdir(filename + "_dir")
    for names in zip_file.namelist():
        zip_file.extract(names, filename + "_dir/")
    zip_file.close()
  • .rar 文件
import rarfile

def unrar(filename):
    rar = rarfile.RarFile(filename)
    if not os.path.isdir(filename + "_dir"):
        os.mkdir(filename + "_dir")
    os.chdir(filename + "_dir")
    rar.extractall()
    rar.close()

可以看到,四种解压代码略有不同,推荐大家实际演示中自己体会一下差别
解压后配合 os.remove() 就可以删除压缩包

现在看看逻辑框架补上解压函数后的内容:

for filename in filename_lst:
    if '.' in filename:
        suffix = filename.split('.')[-1]
        if suffix == 'gz':
            new_filename = ungz(filename)
            os.remove(filename)
            if new_filename.split('.')[-1] == 'tar':
                untar(new_filename)
                os.remove(new_filename)  
        if suffix == 'tar':
            untar(filename)
            os.remove(filename)
        if suffix == 'zip':
            unzip(filename)
            os.remove(filename)
        if suffix == 'rar':
            unrar(filename)
            os.remove(filename)

实现实时检测

比较简单的方法就是建立 while True 死循环配合 time.sleep() 睡眠,框架如下:

import time

while True:
    func()
    time.sleep(5) # 睡眠秒数可以设置大一点避免过度占用资源

将第二步的实现代码改为函数并放在循环框架中就可以完成本次需求
完整代码如下

import glob
import os
import gzip
import tarfile
import zipfile
import rarfile
import time

path = r'C:\xxxx\download'
file_lst = glob.glob(path + '/*')
filename_lst = [os.path.basename(i) for i in file_lst]

def ungz(filename):
    filename = filename[:-3]
    gz_file = gzip.GzipFile(filename)
    with open(filename, "w+") as file:
        file.write(gz_file.read())
    return filename

def untar(filename):
    tar = tarfile.open(filename)
    names = tar.getnames()
    if not os.path.isdir(filename + "_dir"):
        os.mkdir(filename + "_dir")
    for name in names:
        tar.extract(name, filename + "_dir/")
    tar.close()

def unzip(filename):
    zip_file = zipfile.ZipFile(filename)
    if not os.path.isdir(filename + "_dir"):
        os.mkdir(filename + "_dir")
    for names in zip_file.namelist():
        zip_file.extract(names, filename + "_dir/")
    zip_file.close()

def unrar(filename):
    rar = rarfile.RarFile(filename)
    if not os.path.isdir(filename + "_dir"):
        os.mkdir(filename + "_dir")
    os.chdir(filename + "_dir")
    rar.extractall()
    rar.close()

def unzip_files():
    for filename in filename_lst:
        if '.' in filename:
            suffix = filename.split('.')[-1]
            if suffix == 'gz':
                new_filename = ungz(filename)
                os.remove(filename)
                if new_filename.split('.')[-1] == 'tar':
                    untar(new_filename)
                    os.remove(new_filename)
            if suffix == 'tar':
                untar(filename)
                os.remove(filename)
            if suffix == 'zip':
                unzip(filename)
                os.remove(filename)
            if suffix == 'rar':
                unrar(filename)
                os.remove(filename)

while True:
    unzip_files()
    time.sleep(5)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342