Python中遇到"UnicodeDecodeError: ‘gbk’ codec can’t decode bytes in position 0: illegal multibyte

最近在写python(3.6.1)时,遇到了标题上的错误,在网上搜索各种方案,都不好使,网上的方案很多,一般是修改编码集,例如utf-8, gbk:

fileHandler = open('../report.html', mode='r', encoding='UTF-8')

但上面的方法对有的情况起作用,有的情况却不起作用。还有修改读写方式为二进制的,虽然不会再报错,但结果却不对。


这些问题在于没有找到根本原因,出现这种错误的原因是, python试图以默认的解码方式(例如utf-8)去解码文件的时候发现无法解码,这才报了错误,也就是说,python不知道这个文件真正的编码是什么。


那我们要解决这样的错误,要么知道该文件真正的编码方式,在open文件的时候指定相应的编码,要么提前把这个文件转换编码,然后再读取,这样就会成功。

例如,我要读取的文件e:\worksheet.txt是一个由excel 2010保存出来的txt文件,它的编码方式和格式都不清楚,python默认编码、指定utf-8以及gbk都不能正确执行。现在知道这问题是编码导致,我直接把该文件用notepad打开,然后另存一个文件,这时候它就会用windows默认的编码保存了。在python里依次代码为utf-8没有成功,修改成gbk成功。这么说,windows默认用gbk保存了中文。

------------------------------------------------------------------------------

上面是我的看法,网上还看到一些有价值的帖子,也贴出来参考:

原文地址:http://blog.csdn.net/cz626626/article/details/71083309

在python3读取txt文件时,遇到上面问题是因为: 
txt文件存的是utf8编码,打开文件的时候没有指定编码,文件虽然是utf8编码,但是在计算机里面存储的还是unicode编码数据,即计算机是将文件的内容按照utf8编码成unicode后存到了硬盘上,而现在执行f.read()的时候,因为没有指定编码,f.read()可能是发现文件中有中文,所以按照gbk来试图将unicode解码,但是因为文件本身是utf8的,所以解码失败。

修改方法1:

FILE_OBJECT= open('aaa.txt','r', encoding='UTF-8')

修改方法2:

FILE_OBJECT= open('aaa.txt','rb')

建议使用第一种,定义数据读取的编码,第二种会以二进制的方法读取数据,会给后面带来麻烦。


------------------------------------------------------------------------

另外一篇:

dhttps://www.crifan.com/summary_python_unicodedecode_error_possible_reasons_and_solutions/?utm_source=tuicool&utm_medium=referral

【背景】

问题参见:

python2.7 urllib2 抓取新浪乱码

中的:

报错的异常是   
UnicodeDecodeError: ‘gbk’ codec can’t decode bytes in position 2-3: illegal multibyte sequence

此问题,还是很具有代表性的,此处,专门整理如下:

 

【Python中如何处理UnicodeDecodeError和UnicodeEncodeError】

简答:

1.仔细分析错误的类型

2.搞清自己处理的字符串是什么类型的

3.然后换用这种的字符编码去编码或解码

 

详解:

以上面的错误:

UnicodeDecodeError: ‘gbk’ codec can’t decode bytes in position 2-3: illegal multibyte sequence

为例,去解释,如何处理这类问题:

1.仔细分析错误的类型

(1)错误是Unicode的编码还是解码

对于此处,错误是:

UnicodeDecodeError

的类型的。

此英文,对应的中文的含义,其实已经很清楚了:

Unicode的解码(Decode)出现错误(Error)了

而对于上面这句,我们可以推断出:

  • 你当前正在处理某种编码类型的字符串
  • 此处你要处理字符串,是想要将该字符串去解码decode,变成Unicode
  • 但是将该字符串解码变成Unicode期间,却出错了

 (2)所用的是何种编码

好的,接着看上面的错误:

‘gbk’ codec can’t decode

使得错误信息更加明显了:

  • 你此处,要将字符串解码为Unicode,是以gbk编码的方式去解码(该字符串变成Unicode)的
  • 但是此处通过gbk的方式,却无法解码(can’t decode )
  • 注:此处的codec,意思是:编解码(器),是Python内部的模块,用来编码或解码(字符串)的

 

(3)错误位置

bytes in position 2-3

此处的信息,后续一般也很少用到。

有时候会用于定位具体错误的位置。

此处暂且忽略。

 (4)错误的细节错误类型

illegal multibyte sequence

翻译为中文为:

非法的,多字节,序列

简单说就是:

没法(解码)了。

 【原因及解决办法】

好了,针对于上面所分析出来的信息:

将一个字符串,通过gbk的方式,去解码,想要获得Unicode字符串,结果出错了

我们来说说原因和解决办法:

此种错误,有几种可能: 
(1)要处理的字符串本身不是gbk编码,但是你却以gbk编码去解码 
比如,字符串本身是utf-8的,但是你却用gbk去解码utf-8的字符串,所以结果不用说,则必然出错

则必然会出现这类的错误,说是,用gbk的方式去解码字符串,想要获得Unicode字符串,但是结果却解码出错了

解决办法:

如果你确定当前字符串,比如抓取网页通过charset=utf-8,已经确定html的字符串是utf-8的,

则可以直接去通过utf-8去解码。

 

相关参考内容:

详解抓取网站,模拟登陆,抓取动态网页的原理和实现(Python,C#等)

中的:

【整理】关于HTML网页源码的字符编码(charset)格式(GB2312,GBK,UTF-8,ISO8859-1等)的解释

 

而如果本身对于所处理的字符串,不太清楚是什么编码类型的,可以尝试去通过chardet等模块,去检测看看:

【教程】如何用Python中的chardet去检测字符编码类型

然后搞清楚了,确定了,字符串是什么类型,然后再去解码。

提示:

关于字符串编码的类型,作为背景学习知识,也应该去了解一下。

这样对于以后处理字符串方面,会更有帮助。

 

(2)你没有主动的去将字符串编码为对应的Unicode,但是结果也报上面的UnicodeDecodeError的错误

这个情况,最常见的,就是我之前在:

【总结】Python 2.x中常见字符编码和解码方面的错误及其解决办法

所整理过的:

“Python中,打印字符串时,字符串本身的编码,与输出终端中所用编码不匹配”

此处不再赘述,只简要再说一下:

如果你本身拿到的是utf-8等,非gbk编码的字符串,然后用print去打印出来

在windows系统就是输出到cmd中

而cmd中,(对于多数中国人所用的是中文的系统)默认字符编码是gbk

从而导致此种现象:

python要将utf-8编码的字符串,在gbk的cmd的中打印出来

所以先要去尝试,用gbk的编码,解码为Unicode然后再打印出来

结果就出现此处的错误了。

详细解释,还是参见上面的教程。

其中还有示例代码的。

 

(3)处理的字符的确是gbk的,但是其中夹杂的部分特殊字符,是gbk编码中所没有的 
如果有些特殊字符是GB18030中有的,但是是gbk中没有的。 
则用gbk去解码,去所不支持的字符,也比如会出错。 
所以,此种情况,可以尝试用和当前编码(gbk)所兼容的但所包含字符更多的编码(gb18030)去解码,或许就可以了。

提示:

如果对于GBK,GB18030,以及GB2312不了解,则可参考:

字符编码简明教程

 另外:

如果遇到其他的,类似此中错误的,比如:

UnicodeEncodeError: 'gbk' codec can't encode character u'\u3232' in position 0: illegal multibyte sequence

等类型的错误,你就可以按照上述的思路,去分析,错误的现象,原因,然后通过自己,就可以找到解决办法了。

 注:

其他和这类错误相关的,也还有一些可以参考的:

【总结】静态网页抓取,动态网页抓取,模拟登陆的注意事项和心得

中的:“返回的html内容是乱码”

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值