在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,更无法打印出来
注:
对于任何字符,都可以去这里:
而查到,对应的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去处理的:
(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)