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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章