Python UnicodedecodeError编码问题解决方法汇总

作者:tomorrownan 时间:2023-10-07 09:28:20 

今天真的被编码问题一直困扰着,午休都没进行。也真的见识到了各种编码。例如:gbk,unicode、utf-8、ansi、gb2312等。
如果脚本程序中编码与文件编码不一致,就会报出UnicodedecodeError的错误。

1.情景一

读文件时常需要将内容转为utf8,文字可正常显示,但是如果原文件内容编码格式不是utf8就会报错UnicodedecodeError。如下:

问题:

try:
    fileObj = open(os.path.join(path,filename),'r')
      textLines = fileObj.readlines()
      fileObj.close()
  except IOError as err:
      print('打开文件%s失败:%s'%(filename,err))

Python UnicodedecodeError编码问题解决方法汇总

解决方法:

代码改为:

try:
    fileObj = open(os.path.join(path,filename),'r',encoding='utf-8')
      textLines = fileObj.readlines()
      fileObj.close()
  except IOError as err:
      print('打开文件%s失败:%s'%(filename,err))

此方法可以解决一部分编码问题,但是却不是一劳永逸的,在下一批文件因其他功能扩展需要读写时,上面程序又报出UnicodedecodeError:gbk codec cant decode…

2.情景二

针对上面的编码问题没有得到很好的解决,决定专门写一个批量将文件夹下面的文件编码格式改为utf-8的脚本,网上查资料得知python的第三方模块chardet,但是要安装这个扩展库。
chardet是一个非常好的编码识别模块,

1.chardet库的安装
在外网机上安装这个模块是特表简单的,直接执行pip chardet install命令即可,但是我的工作环境是内网,因为这个项目要处理的文件量多且大,所以也在Windows系统(编码问题比Linux多),因此安装chardet模块也花费了好大一会时间。

a.在外网下载好安装包chardet-3.0.4.tar.gz。
b.解压缩放在python安装路径\Python\Lib\site-packages下,命令切换到当前目录,执行python setup.py install。
c.安装完毕后import chardet仍然未成功

上面的安装步骤是没有问题的,我想应该是因为某个依赖没有安装吧,因此突然想到一个比较笨的方法:就是在外网机上执行pip chardet install先安装好,然后到安装目录下把关于chardet的安装目录chardet和chardet-3.0.4.dist-info拷贝到内网机\Python\Lib\site-packages下,再import chardet时竟然成功了。。。。

Python UnicodedecodeError编码问题解决方法汇总

编写文件编码格式转换脚本

#!/usr/bin/python
# _*_ coding:utf-8 _*_
#更改文件编码,文件统一改为utf-8无BOM格式
import os
from chardet import detect

#文件夹目录
g_filedir = r'C:\Users\Desktop\nmg\SS'

def runcoding(path):
   for filename in os.listdir(path):
       if filename.endswith('.txt'):
           with open(os.path.join(path,filename),'rb+') as fileObj:
               fileContent = fileObj.read()
               #判断编码格式
               encodingtype = detect(fileContent)['encoding']

print(encodingtype)
               #格式转换
               fileContent = fileContent.decode(encodingtype).encode('utf8')
               #写回文件
               fileObj.seek(0)
               fileObj.write(fileContent)

if __name__=="__main__":
   runcoding(g_filedir)

在处理字符串时,常常会遇到不知道字符串是何种编码,如果不知道字符串的编码就不能将字符串转换成需要的编码。上面的chardet模块就能很好的解决这个问题。

此时当前文件夹下的文件顺利的进行了读写,再次readlines时没有报UnicodedecodeError问题。可以检测到gbk、Unicode、utf8、utf16、utf8(big)等编码,也不用再一个编码一个编码的去转换,一个文件一个文件的转换。以为编码问题终于一次性解决了。

但是。。。到另一个省份的一批文件要进行批量操作时,进行到第49个文件就终止了,又报出UnicodedecodeError:‘utf8’ codec cant decode问题。。。。用上面脚本对该省份文件夹下文件进行格式转换时报出错误:TypeError:decode() argument 1 must be str ,not None。

3.情景三

针对情景2的问题,仍要继续排查编码的问题,根据运行的情景二的脚本时报出的错误在脚本中添加代码,打印出返回None的文件名。

修正代码

#!/usr/bin/python
# _*_ coding:utf-8 _*_
#更改文件编码,文件统一改为utf-8无BOM格式
import os
from chardet import detect

#文件夹目录
g_filedir = r'C:\Users\Desktop\nmg\SS'

def runcoding(path):
   for filename in os.listdir(path):
       if filename.endswith('.txt'):
           with open(os.path.join(path,filename),'rb+') as fileObj:
               fileContent = fileObj.read()
               #判断编码格式
               encodingtype = detect(fileContent)['encoding']
               #ansi编码检测结果为none
               if encodingtype==None:
                   print(filename)
                   continue
               #print(encodingtype)
               #格式转换
               fileContent = fileContent.decode(encodingtype).encode('utf8')
               #写回文件
               fileObj.seek(0)
               fileObj.write(fileContent)

if __name__=="__main__":
   runcoding(g_filedir)

然后定位到那个文件,记事本打开再另存为查看编码方式为ANSI,或者使用notpad++查看编码类型。

记事本默认是以ANSI编码保存文本文档的,而正是这种编码存在的bug招致了上述怪现象。假如保存时选择Unicode、Unicode (Big Endian)、UTF-8编码,就正常了。此外,假如以ANSI编码保存含有某些特别符号的文本文档,再次打开后符号也会变成英文问号。

这里可以得知,文件以ansi编码时decode()函数返回的事None。

4. chardet模块detect()函数

chardet模块中的chardet.detect()函数可以检测编码。返回结果如下:

data = '我最美'.encode('gbk')
chardet.detect(data)

Out[103]: {'confidence': 0.73, 'encoding': 'ISO-8859-1', 'language': ''}

输出结果confidence为概率。

encoding为字符串的编码方式。

编码问题最困扰人,好在今天顺利解决了,各个省份的数据也都按照格式要求修改完毕,已经上报到各省份,晚上就花点时间整理以下喽。

来源:https://blog.csdn.net/w1418899532/article/details/84308049

标签:Python,UnicodedecodeError,编码
0
投稿

猜你喜欢

  • 基于Python爬取51cto博客页面信息过程解析

    2023-06-11 16:27:37
  • Express框架定制路由实例分析

    2024-05-11 10:16:42
  • 如何在页面中快捷地添加翻页按钮?

    2010-06-26 12:33:00
  • Python requests及aiohttp速度对比代码实例

    2023-11-22 14:40:37
  • Numpy数组转置的两种实现方法

    2023-01-22 16:36:54
  • mysql共享锁与排他锁用法实例分析

    2024-01-20 15:15:26
  • GO必知必会的常见面试题汇总

    2023-07-14 01:47:07
  • 如何避免asp的SQL的执行效率低

    2009-01-08 18:18:00
  • 基于Git的常用撤销技巧与解决冲突方法(推荐)

    2023-07-01 19:20:28
  • 全面解析Bootstrap表单使用方法(表单样式)

    2024-05-10 14:08:28
  • python 实现数据库中数据添加、查询与更新的示例代码

    2023-10-08 04:09:51
  • [译]在线广告及其在网页设计中的重要性

    2009-02-06 13:36:00
  • 解决无法配置SQL2005问题

    2024-01-22 15:56:51
  • 一文详解MySQL主从同步原理

    2024-01-24 03:00:59
  • 详解Python实现图像分割增强的两种方法

    2022-08-16 20:23:50
  • python文件目录操作之os模块

    2023-01-10 14:22:59
  • 使用python加密主机文件几种方法实现

    2021-03-06 03:16:12
  • 浅析PyTorch中nn.Module的使用

    2021-10-29 14:04:53
  • Python中常见的加密解密算法总结

    2021-10-18 12:13:17
  • python Pandas如何对数据集随机抽样

    2023-10-02 08:28:13
  • asp之家 网络编程 m.aspxhome.com