在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)