您好,登录后才能下订单哦!
这篇文章主要介绍“Python UnicodedecodeError编码问题如何解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python UnicodedecodeError编码问题如何解决”文章能帮助大家解决问题。
读文件时常需要将内容转为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))
解决方法:
代码改为:
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…
针对上面的编码问题没有得到很好的解决,决定专门写一个批量将文件夹下面的文件编码格式改为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时竟然成功了。。。。
编写文件编码格式转换脚本
#!/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。
针对情景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。
chardet模块中的chardet.detect()函数可以检测编码。返回结果如下:
data = '我最美'.encode('gbk') chardet.detect(data) Out[103]: {'confidence': 0.73, 'encoding': 'ISO-8859-1', 'language': ''}
输出结果confidence为概率。
encoding为字符串的编码方式。
关于“Python UnicodedecodeError编码问题如何解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。