python3 UnicodeEncodeError的错误

我遇到问题的情况是:

在win10系统下输入json,其中有gbk无法识别的字符,进而无法在cmd下输出,也无法IO write()到本地文件。

参考此篇:【总结】Python 2.x中常见字符编码和解码方面的错误及其解决办法 点击打开链接

描述参考:


Python中,打印含某些特殊字符的Unicode类型字符串,但是输出终端中字符编码集中不包含这些特殊字符

现象

虽然已经获得了Unicode的字符串了,但是当打印Unicode类型的字符串,到某些终端中时,结果却还是出错了。

比如,下面的例子中,就是把Unicode字符串,打印到Windows的cmd中,结果出错:

python_2.x_print_unicode_still_error.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------------------------------------
Function:
【总结】Python中常见字符编码和解码方面的错误及其解决办法
https://www.crifan.com/summary_python_2_x_common_string_encode_decode_error_reason_and_solution
 
Author:     Crifan
Verison:    2012-11-29
-------------------------------------------------------------------------------
"""
  
#任何字符,都可以在:
#http://unicodelookup.com/
#中,查找到对应的unicode的值
 
def python2xPrintUnicodeStillError():
    #http://zhidao.baidu.com/question/500133781.html
    slashUStr = "\\u3232\\u6674"; #(有) 晴
    decodedUniChars = slashUStr.decode("unicode-escape"); #此处已经可以正常获得对应的两个Unicode字符了
    unicodeButContainSpecialChar = decodedUniChars;
    print "unicodeButContainSpecialChar=",unicodeButContainSpecialChar;
     
    #此处在GBK编码的cmd中输出的话,会出现错误的:
    #UnicodeEncodeError: 'gbk' codec can't encode character u'\u3232' in position 0: illegal multibyte sequence
    #那是因为,Unicode字符:0x3232,是个特殊字符,而此字符,在GBK编码字符集中,本身就不包含此特殊字符,所以当然没法把这个特殊字符编码为对应的GBK字符,所以出错,更无法显示
 
###############################################################################
if __name__=="__main__":
    python2xPrintUnicodeStillError();

原因

上述过程中,虽然已经获得了正确的unicode字符串了,但是由于此unicode字符串中包含了一个特殊字符,即那个\u3232,对应的字符,显示出来,像是左右括号中间一个"有"字,即类似于这样的:

(有)

而此特殊字符,GBK字符集中没有,不存在,所以无法将对应的Unicode字符,编码为对应的GBK字符,所以出现UnicodeEncodeError,更无法打印出来

注:

对于任何字符,都可以去这里:

http://unicodelookup.com/

而查到,对应的unicode的值,html中的写法。

提醒:

可以通过输入:

0x3232

而查到该特殊字符。


解决办法

解决办法,则是不同情况,不同处理:

(1)如果对于这些特殊字符,你不是很关心,即使不显示也无所谓,但是希望剩下的,其他大多数的正常的字符都能显示。

即,忽略掉特殊字符,显示哪些能显示的字符, 那么可以改为如下代码:

python_2.x_print_unicode_omit_special.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------------------------------------
Function:
【总结】Python中常见字符编码和解码方面的错误及其解决办法
https://www.crifan.com/summary_python_2_x_common_string_encode_decode_error_reason_and_solution
 
Author:     Crifan
Verison:    2012-11-29
-------------------------------------------------------------------------------
"""
  
#任何字符,都可以在:
#http://unicodelookup.com/
#中,查找到对应的unicode的值
 
def python2xPrintUnicodeOmitSpecial():
    #http://zhidao.baidu.com/question/500133781.html
    slashUStr = "\\u3232\\u6674"; #(有) 晴
    decodedUniChars = slashUStr.decode("unicode-escape"); #此处已经可以正常获得对应的两个Unicode字符了
    unicodeButContainSpecialChar = decodedUniChars;
    #print "unicodeButContainSpecialChar=",unicodeButContainSpecialChar;
     
    #此处在GBK编码的cmd中输出的话,会出现错误的:
    #UnicodeEncodeError: 'gbk' codec can't encode character u'\u3232' in position 0: illegal multibyte sequence
    #那是因为,Unicode字符:0x3232,是个特殊字符,而此字符,在GBK编码字符集中,本身就不包含此特殊字符,所以当然没法把这个特殊字符编码为对应的GBK字符,所以出错,更无法显示
     
    #如果只是想要:
    #显示那些正常可以显示的字符,忽略个别特殊不能显示的字符
    #那么可以改为如下代码:
    encodedShowableGbk = unicodeButContainSpecialChar.encode("GBK", "ignore");
    print "encodedShowableGbk=",encodedShowableGbk; #encodedShowableGbk= 晴
 
###############################################################################
if __name__=="__main__":
    python2xPrintUnicodeOmitSpecial();

注:我之前遇到的一个情况,就是通过添加ignore去处理的:

【已解决】UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\u200e’ in position 43: illegal multibyte sequence

(2)如果必须要显示这些字符,或者说必须要保留这些字符。那么本身对于打印这个需求来说,是可以不打印的,因为本身已获得了正常的Unicode字符了。

然后剩下的,只是尽量你自己所需要的后续的处理即可。

即, 已经得到了正确的unicode字符了,后续该咋办咋办,可以不打印的时候,就不打印,也就不会出错了。

 

举一反三

如果以后遇到这种,虽然已获得了Unicode字符串,但是还是无法打印等情况,则就要注意去调查一下,是否是由于此处有特殊字符,不存在于输出目标所用字符集中,才导致此问题的。


- - - - - -

但在具体实现时发现有问题,其中关键语句:

string_gbk = string.encode("GBK", "ignore")

实际操作时,还应decode一下,即:

string_gbk = string.encode("GBK", "ignore")
string = string_gbk.decode("GBK")
print(string)
save.write(string)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章