Python解压缩zip文件出现乱码问题的解决方案Python解压缩zip文件出现乱码问题的解决方案Python解压缩zip文件出现乱码问题的解决方案Python解压缩zip文件出现乱码问题的解决方案
  • 首页
  • 博客
  • 文件
  • 书签
  • 分析
  • 登录
Search
Generic filters

Python解压缩zip文件出现乱码问题的解决方案

Published by admin at 2022年3月19日
Categories
  • Python
Tags

参考:python 之路,致那些年,我们依然没搞明白的编码 https://www.cnblogs.com/alex3714/articles/7550940.html

1. python使用zipfile解压文件中文乱码问题

Python中的zipfile模块用来解压缩ZIP文件非常方便,但是如果ZIP文件的子文件的文件名里含有中文的话,解压出出来的文件的文件名却是乱码!这到底是为什么呢?

查看zipfile的源码后,终于找到原因:

if zinfo.flag_bits & 0x800:
    # UTF-8 filename
    fname_str = fname.decode("utf-8")
else:
    fname_str = fname.decode("cp437")

原来编码不能被正确识别为utf-8的时候,会被是被识别并decode为cp437编码,如果原来是gbk编码的话就会变成乱码。
知道是什么原因后,解决的办法也很简单,那就是将文件名先使用cp437编码encode,然后再用gbk编码decode即可,来试试吧!

import os
import zipfile

is_zip = zipfile.is_zipfile(filePath)
if is_zip:
    zip_file_contents = zipfile.ZipFile(filePath, 'r')
    for file in zip_file_contents.namelist():
        filename = file.encode('cp437').decode('gbk')#先使用cp437编码,然后再使用gbk解码
        print(filename)
        zip_file_contents.extract(file,release_file_dir)#解压缩ZIP文件
        os.chdir(release_file_dir)#切换到目标目录
        os.rename(file,filename)#重命名文件

2. python使用zipfile解压文件中文乱码问题

中文在编程中各种坑爹,python3下中文乱码这个问题令人头疼。看了alex的文章,才有种恍然大悟的感觉。
一句话,就是转换成unicode,压缩前是什么编码,使用什么编码encode再decode回来

先看测试代码:

# -*- coding: utf-8 -*-
import zipfile

# 默认模式r,读
zip_file = zipfile.ZipFile("/Users/feise.zip", 'r')
# 返回所有文件夹和文件
zip_list = zip_file.namelist()
for file in zip_list:
    print(file)
    print(file.encode('utf-8'))

真实文件名
绯色 / w1985jc / 沈嫣日记 / 8
_【沈嫣日记】(33 - 完).txt  

print(file):
τ│╔½ / ú≈ú▒ú╣ú╕ú╡úΩúπ /╔≥µ╠╚╒╝╟ / 8
_í╛╔≥µ╠╚╒╝╟í┐ú¿33 -═Ωú⌐.txt

print(file.encode('utf-8')):
b'\xcf\x84\xe2\x94\x82\xe2\x95\x94\xc2\xbd/\xc3\xba\xe2\x89\x88\xc3\xba\xe2\x96\x92\xc3\xba\xe2\x95\xa3\xc3\xba\xe2\x95\x95\xc3\xba\xe2\x95\xa1\xc3\xba\xce\xa9\xc3\xba\xcf\x80/\xe2\x95\x94\xe2\x89\xa5\xc2\xb5\xe2\x95\xa0\xe2\x95\x9a\xe2\x95\x92\xe2\x95\x9d\xe2\x95\x9f/8_\xc3\xad\xe2\x95\x9b\xe2\x95\x94\xe2\x89\xa5\xc2\xb5\xe2\x95\xa0\xe2\x95\x9a\xe2\x95\x92\xe2\x95\x9d\xe2\x95\x9f\xc3\xad\xe2\x94\x90\xc3\xba\xc2\xbf33-\xe2\x95\x90\xce\xa9\xc3\xba\xe2\x8c\x90.txt'

成功代码,使用cp437可以正确读取部分,但是还有一部分却打印出来\u的编码,因为看了alex的文章,又在catch中加上了utf8的解码方式

# -*- coding: utf-8 -*-
import zipfile

# 默认模式r,读
zip_file = zipfile.ZipFile("/Users/feise.zip", 'r')
# 返回所有文件夹和文件
zip_list = zip_file.namelist()
for file in zip_list:
    print(file)
    print(file.encode('utf-8'))
    try:
        file = file.encode('cp437').decode('gbk')
    except:
        file = file.encode('utf-8').decode('utf-8')
    print(file)
    
一句话,就是转换成unicode,压缩前是什么编码,使用什么编码encode再decode回gbk、utf8

3. 在实际过程中可以对已经先用zipfile进行解压,然后对unzip文件夹中的乱码文件直接进行重命名

具体实现过程如下:

import os

def anti_garbled_code(dir_names):
    os.chdir(dir_names)
    for temp_name in os.listdir('.'):
        try:
            # 使用cp437对文件名进行解码还原
            new_name = temp_name.encode('cp437')
            # win下一般使用的是gbk编码
            new_name = new_name.decode("gbk")
            # 对乱码的文件名及文件夹名进行重命名
            os.rename(temp_name, new_name)
            # 传回重新编码的文件名给原文件名
            temp_name = new_name
        except:
            # 如果已被正确识别为utf8编码时则不需再编码
            pass
        if os.path.isdir(temp_name):
            # 对子文件夹进行递归调用
            anti_garbled_code(temp_name)
            # 记得返回上级目录
            os.chdir('..')

anti_garbled_code(os.getcwd())

发表回复 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

Categories

  • 猫
  • Python
  • MySQL
  • Django
  • Html/CSS
  • JavaScript
  • Vue
  • RegExp
  • php
  • Practice
  • Virtualization
  • Linux
  • Windows
  • Android
  • NAS
  • Software
  • Hardware
  • Network
  • Router
  • Office
  • WordPress
  • SEO
  • English
  • Games
  • Recipes
  • living
  • Memorandum
  • Essays
  • 未分类

归档

©2015-2022 Alaica Blog support@alaica.com