UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\u200e’ in position 43: illegal multibyte sequence


【問題】

python中已獲取網頁:

http://blog.csdn.net/hfahe/article/details/5494895

的html源碼,其時UTF-8編碼的。

提取出其標題部分:

        <span class="link_title"><a href="/hfahe/article/details/5494895">

        在2008 Beijing Perl 大會的演講-使用Mason開發高性能的Web站點‎ 

        </a></span>

中的標題文字:

在2008 Beijing Perl 大會的演講-使用Mason開發高性能的Web站點

然后用:

titleUni = unicode(titleHtml, “UTF-8″);

titleUni = titleHtml.decode(“UTF-8″);

將其解碼成Unicode,但是卻會出錯:

UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\u200e’ in position 43: illegal multibyte sequence

 

【解決過程】

1.Python的編碼問題,GB18030,UTF-8,Unicode等問題,之前遇到過很多次了,也就解決了。此處很奇怪的是,

類似的其他的網頁,比如:

http://blog.csdn.net/v_july_v/article/details/6543438

http://blog.csdn.net/v_july_v/article/details/5934051

等,對應提取出來的內容,都是可以正常解碼為Unicode的。

因為本身其編碼的確是Utf-8的。

2.去試了試用chardet.detect分析其真正編碼的,得到的結果是:

encInfo= {‘confidence': 0.99, ‘encoding': ‘utf-8′}

也是和其他網頁內容得到的結果是一樣的。

3.此問題覺得很詭異的是,本身調用UTF-8去decode,但是解碼出錯卻提示的是GBK的,而不是UTF-8相關解碼出錯。

4.找了些其他帖子:

Python UnicodeEncodeError:illegal multibyte sequence

但是討論的都是關於從Unicode編碼為GBK或GB2312,然后出錯的。

而我這里的錯誤是,本身內容是UTF-8的,然后想要還原為Unicode,結果卻提示GBK解碼錯誤的。。。

5.這里:探索UTF-8中文編碼的BOM標記問題提到了,可能是由於UTF-8的BOM造成的不能正常解碼,所以試着去將返回的html導出為html文件,然后用Notepad++查看,結果還是沒看出是否有BOM,反正是文字內容,都可以查看到的。

然后也試了類似代碼:

titleUni = titleHtml[1:].decode(“UTF-8″);

 

titleUni = titleHtml[2:].decode(“UTF-8″);

但是都還是不行。

后來在這里也看到了,關於UTF-8的BOM的問題的解釋,但同樣不是我要的。

6.在這里:Python Unicode與中文處理(文摘),看到了:

s.decode(‘gbk’, ‘ignore’).encode(‘utf-8′)

然后才想起來,之前是看到過類似的解釋,即添加ignore來忽略非法的字符,然后又參考:

python字符串decode中遇到非法字符的問題

然后去找了對應語法:

str.decode([encoding[, errors]])

Decodes the string using the codec registered for encoding. encoding defaults to the default string encoding. errors may be given to set a different error handling scheme. The default is 'strict', meaning that encoding errors raiseUnicodeError. Other possible values are 'ignore''replace' and any other name registered via codecs.register_error(), see section Codec Base Classes.

New in version 2.2.

Changed in version 2.3: Support for other error handling schemes added.

Changed in version 2.7: Support for keyword arguments added.

試了:

titleUni = titleHtml.decode(“UTF-8″, ‘ignore’);

和:

titleUni = titleHtml.decode(“UTF-8″, ‘replace’);

但是結果仍是:

print “titleUni=”,titleUni;

會出現上述“’gbk’ codec can’t encode”的錯誤。

但是后來無意間發現,在打印titleUni之前,添加了一行調試代碼:

print “len(titleUni)=”,len(titleUni);

卻是可以正常打印的,這就說明,此處的titleUni變量,正常解碼為Unicode的值了,即上述decode是正常的。

然后又重新試了試,之前的:

titleUni = titleHtml.decode(“UTF-8″);

結果也是一樣的,即print “len(titleUni)=”,len(titleUni);也是可以正常輸出的。

然后此時才明白,原來出現’gbk’ codec can’t encode”的錯誤的根本原因是,對於前面的,不論是用

titleHtml.decode(“UTF-8″);

還是

titleHtml.decode(“UTF-8″, ‘ignore’);

還是

titleHtml.decode(“UTF-8″, ‘replace’);

都是可以得到正常的titleUni的Unicode字符的,然后對於此Unicode的字符,需要print出來的話,由於本地系統是Win7中的cmd,默認codepage是CP936,即GBK的編碼,所以需要先將上述的Unicode的titleUni先編碼為GBK,然后再在cmd中顯示出來,然后由於titleUni中包含一些GBK中無法顯示的字符,導致此時提示“’gbk’ codec can’t encode”的錯誤的。

【總結】

對於此(類)問題:

(1)出現UnicodeEncodeError –> 說明是Unicode編碼時候的問題;

(2) ‘gbk’ codec can’t encode character –> 說明是將Unicode字符編碼為GBK時候出現的問題;

此時,往往最大的可能就是,本身Unicode類型的字符中,包含了一些無法轉換為GBK編碼的一些字符。

解決辦法是:

  • 方案1:

在對unicode字符編碼時,添加ignore參數,忽略無法無法編碼的字符,這樣就可以正常編碼為GBK了。

對應代碼為:

gbkTypeStr = unicodeTypeStr.encode(“GBK“, ‘ignore’);
  • 方案2:

或者,將其轉換為GBK編碼的超集GB18030 (即,GBK是GB18030的子集):

gb18030TypeStr = unicodeTypeStr.encode(“GB18030“);

對應的得到的字符是GB18030的編碼。

【題外話】

對於上述中,將原先的utf-8的字符轉換為Unicode的時候,其實更加安全的做法,也可以將:

titleUni = titleHtml.decode(“UTF-8″);

替換為:

titleUni = titleHtml.decode(“UTF-8″, ‘ignore’);

這樣可以實現,即使對於那些,相對來說是無關緊要的一些特殊字符,也可以成功編碼,避免編碼出錯,提高程序的健壯性。

 


【后記 2012-12-01】

后來,專門花精力,總結了最常見的一些類型,感興趣的可以去看看:

【總結】Python 2.x中常見字符編碼和解碼方面的錯誤及其解決辦法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM