最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\u200e’ in position 43: illegal multibyte sequence

Python crifan 41013浏览 0评论

【问题】

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 raise UnicodeError. 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中常见字符编码和解码方面的错误及其解决办法

 

转载请注明:在路上 » 【已解决】UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\u200e’ in position 43: illegal multibyte sequence

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (20)

  1. 李兄,找教程又找到你了!哈哈~~~
    seofangfa.com5年前 (2019-05-20)回复
  2. 解决了python小白的问题,感激不尽
    爱你的小白5年前 (2019-04-03)回复
  3. 感谢,非常感谢!!!!!如果不是博主这篇文章,我这个程序可能得纠结好久
    秋念5年前 (2019-01-22)回复
  4. 感谢,终于找到解决方法了,节省了我很多时间
    jc5年前 (2018-10-31)回复
  5. 感谢
    小白7年前 (2017-08-09)回复
  6. 很奇怪,为什么python的文档解释一个问题都要说这么多旁的呢? 不是我质疑楼主啊,我单纯只是好奇这个问题,很多文档都有这种现象。 类似问题如果出现在java和C里,相关的文档解释起来只会用四分之一或者三分之一的篇幅。是单纯做py的人的一种习惯吗?那这种习惯又是如何造成的呢?这问题我思考很久了。
    ge8年前 (2016-07-08)回复
    • 解释问题容易说很多旁的,是我自己的问题。和是否python没关系。至于其他语言,解释的就很少。我的感觉是: 1.要么是别的语言,设计接口设计的更加精妙(精炼和巧妙),所以无需更多赘述即可解释清楚 2.要么是:别的语言的文档,往往解释的不够充分,不够到位-》等作为开发者的你遇到坑了,回头看文档,也找不到对应的解释 以我目前的判断: 之前Java或C,之所以解释的少,可能更多的是属于后者吧。 个人意见,仅供参考。
      crifan8年前 (2016-07-15)回复
  7. crifan 给自己的评论,看看能否成功发布评论。
    crifan9年前 (2015-08-31)回复
  8. title = titleHtml.decode("utf8") 没错就说明不是这句的问题,而是print的问题 搜到这里,找到了解释...tks...
    magicdanw10年前 (2014-07-22)回复
  9. 谢谢博主,昨天爬中文网站的时候也出现了这个问题,折腾了好久都没有解决。最后还是靠了你的这篇文章。另,本打算小小感谢一下,点击捐赠链接却发现支付宝的收款主页停止服务。
    GloryWu10年前 (2014-07-22)回复
    • 谢谢好意。我最近会抽空给出我的支付宝的账户的,这样有意愿捐赠的,就可以直接支付宝转账了。
      crifan10年前 (2014-07-28)回复
  10. html语言中有一个non-breaking space,可以写作&nbsp,这个&nbsp在中文的windows7上无法识别,结果会出现这个错误: UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 4425: illegal multibyte sequence 目前网上说的办法都无法解决这个问题,无论是来回的encode,decode ignore,是修改windows7的cmd.exe编码码语言从gbk(中文)到unicode的utf-8,还是把\xa0替换为空格! 我最后解决问题的方法是decode为字符串后,随便用个东西,比如说空格或者C2A0,来替换换&nbsp,这样以后再用BeautifulSoup或者打印什么的就都没问题了 具体的操作语句为(我用的是python 3.3.3): the_page = response.read().decode().replace('&nbsp', 'C2A0')
    Littlefairy10年前 (2014-04-11)回复
    • 不好意思,一马虎看漏了一个分号。 &nbsp 应该写成   此外,替换为C2A0也没什么作用,还是替换为空格吧
      Littlefairy10年前 (2014-04-11)回复
    • 我是参照博主的方法,在向cmd输出前再重编码为GB18030解决的 print response.read().decode("UTF-8").encode("GB18030")
      feifei4359年前 (2014-11-19)回复
      • 此方法成功,感谢!!!!
        十五8年前 (2016-08-29)回复
  11. 感谢~终于知道是Windows的问题,纠结了好久。list没有encode属性,不过分离出里面的元素可以正常显示。
    江南胡杨11年前 (2013-08-21)回复
  12. 讲得实在是太清楚了。一直没想到是windows命令行的问题。感激不尽。没给你捐款我很愧疚。推荐你挂google广告
    easier11年前 (2012-12-20)回复
89 queries in 0.178 seconds, using 22.29MB memory