zoukankan      html  css  js  c++  java
  • 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中常见字符编码和解码方面的错误及其解决办法

  • 相关阅读:
    Linux 共享库
    使用Visual Studio(VS)开发Qt程序代码提示功能的实现(转)
    ZOJ 3469 Food Delivery(区间DP)
    POJ 2955 Brackets (区间DP)
    HDU 3555 Bomb(数位DP)
    HDU 2089 不要62(数位DP)
    UESTC 1307 windy数(数位DP)
    HDU 4352 XHXJ's LIS(数位DP)
    POJ 3252 Round Numbers(数位DP)
    HDU 2476 String painter (区间DP)
  • 原文地址:https://www.cnblogs.com/zl0372/p/python_str_code.html
Copyright © 2011-2022 走看看