python 字符编码处理_python 字符编码处理问题总结 彻底击碎乱码!

Python中常常遇到这种字符编码问题,尤其在处理网页源代码时(特别是爬虫中):

UnicodeDecodeError: ‘XXX' codec can't decode bytes in position 12-15: illegal multibyte...

以下以汉字'哈'来解释作演示样例解释全部的问题。汉字“哈”的各种编码例如以下:

1  UNICODE(UTF8-16): 0xC854

2  UTF-8: 0xE59388

3  GBK: 0xB9FE

除此之外还有如gb2312, big5等。比如一些含有繁体字的页面。比方www.google.com.hk首页中用的就是big5码。

不知道港台的码农同一时候处理简体字繁体字是不是更郁闷 :)

一直以来,python中的中文编码就是一个大问题。为他他并不能智能识别编码,而实际上其它语言也非常难做到。

在html的header里一般都能够找到字符编码比如:

当然这不是我们研究的重点。很多其它的时候是我们得知一个字符串是GBK编码。 而要用print等正确的打印出来却不easy...

首先,在python中提到unicode。一般指的是unicode对象。比如'哈哈'的unicode对象为u'\u54c8\u54c8'

而str是一个字节数组,这个字节数组表示的是对unicode对象编码后(如utf-8、gbk、cp936、GB2312)的存储的格式。这里它

仅是一个字节流,没有其他的含义,假设你想使这个字节流显示的内容有意义,就必须用正确的编码格式,解码显示。

比如:(注意是在windows下)

s = u'哈哈'

s_utf8 = s.encode('utf-8')

pirnt s_utf8

>>> 鍝堝搱

悲剧...

s_utf8这时实际上是'\xe5\x93\x88\xe5\x93\x88'

而以下的代码才干够正常显示:

s_gdb = s.encode('gbk')  # s_gdk 这时是'\xb9\xfe\xb9\xfe'

print s_gbk

>>> 哈哈      #正常了

由于print语句它的实现是将要输出的内容传 送了操作系统,操作系统会依据系统的编码对输入的字节流进行编码。这就解释了

utf-8格式的字符串“哈哈”。输出的是“鍝堝搱”,由于 '\xe5\x93\x88\xe5\x93\x88'用GB2312去解释,其显示的出来就

“鍝堝搱”。

这里再强调一下,str记录的是字节数组。仅仅是某种编码的存储格式。至于输出到文件或是打印出来是什么格式,

全然取决其解码的编码将它解码成什么样子。

这里再对print进行一点补充说明:当将一个unicode对象传给print时。在内部会将该unicode对象进行一次转换,

转换成本地默认编码(这仅是个人推測)

str和unicode对象的转换。通过encode和decode实现,详细使用例如以下:再次强调windows下:

s = '哈哈'

print s.decode('gbk').encode('utf-8')

>>> 鍝堝搱

反之亦然,有兴趣能够尝试其它转换

有时当我们遇到把s(gbk字符串)直接编码成utf-8的时候,将抛出异常。可是通过调用例如以下代码:

import sys

reload(sys)

sys.setdefaultencoding('gbk')

后就能够转换成功。为什么呢?

在python中str和unicode在编码和解码过程中,假设将一个str直接编码成还有一种编码,会先把str解码成unicode,

採用默认编码,一般默认编码是anscii,所以在上面演示样例代码中第一次转换的时候会出错。

当设定当前默认编码为'gbk'后。就不会出错了。

至于reload(sys)是由于Python2.5 初始化后会删除 sys.setdefaultencoding 这种方法。我们须要又一次加载。

一般不推荐这样使用。本来reload都是应该避免使用的函数。

对于操作不同文件的编码格式的文件,也会遇到这种问题

建立一个文件test.txt,文件格式用ANSI,内容为:

abc中文

然后用python来读取

# coding=gbk

print open("Test.txt").read()

结果:abc中文

把文件格式改成UTF-8:

结果:abc涓枃。显然,这里须要解码:

# coding=gbk

import codecs

print open("Test.txt").read().decode("utf-8")

结果:abc中文

上面的test.txt我是用Editplus来编辑的,但当我用Windows自带的记事本编辑并存成UTF-8格式时。

执行时报错:

Traceback (most recent call last):

File "ChineseTest.py", line 3, in

print open("Test.txt").read().decode("utf-8")

UnicodeEncodeError: 'gbk' codec can't encode character u'\ufeff' in position 0: illegal multibyte sequence

原来。某些软件,如notepad。在保存一个以UTF-8编码的文件时,

会在文件開始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM)。

因此我们在读取时须要自己去掉这些字符,python中的codecs module定义了这个常量:

# coding=gbk

import codecs

data = open("Test.txt").read()

if data[:3] == codecs.BOM_UTF8:

data = data[3:]

print data.decode("utf-8")

结果:abc中文

最后,有些时候编码搞对了,可是遇到了非法字符。比方产生字符串的来源错误发生,引入了错误值等,这时再次遇到异常

比如:全角空格往往有多种不同的实现方式,比方\xa3\xa0,或者\xa4\x57,

这些字符,看起来都是全角空格。但它们并非“合法”的全角空格

真正的全角空格是\xa1\xa1,因此在转码的过程中出现了异常。

而之前在处理新浪微博数据时,遇到了非法空格问题导致无法正确解析数据。

解决的方法:

将获取的字符串strTxt做decode时,指明ignore,会忽略非法字符,

当然对于gbk等编码。处理相同问题的方法是类似的

strTest = strTxt.decode('utf-8', 'ignore')

return strTest

默认的參数就是strict,代表遇到非法字符时抛出异常;

假设设置为ignore,则会忽略非法字符;

假设设置为replace,则会用?

号代替非法字符;

假设设置为xmlcharrefreplace,则使用XML的字符引用。

其它的以后遇到再总结.....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,字符串是由一系列字节组成的字节数组。当显示字符串时,需要将其解码为特定的字符编码才能正确显示。乱码通常是由于使用错误的字符编码或者编码转换异常引起的。 乱码的情况一般发生在以下两种情况下: 1. 字符编码不一致:当字符串的编码与控制台或其他输出设备的编码不一致时,会导致乱码。比如将使用GBK编码字符串输出到UTF-8编码的控制台,或者将使用UTF-8编码字符串输出到GBK编码的控制台都会导致乱码。 2. 编码转换异常:在进行字符编码转换时,如果源字符串的编码格式不符合目标编码的要求,就会抛出编码转换异常,从而导致乱码的出现。 为了避免乱码问题,在处理字符串时,我们可以采取以下几个方法: 1. 确保输入和输出的设备使用相同的字符编码。比如,如果你的字符串使用GBK编码,那么你应该将控制台或其他输出设备的编码设置为GBK。 2. 在进行字符编码转换时,使用正确的源编码和目标编码。可以使用Python的内置函数encode()和decode()来进行编码转换。 3. 使用Unicode字符串来避免编码问题。Unicode字符串是一种特殊的字符串类型,它可以包含任何字符,而不会出现编码问题。 总之,乱码问题Python中是一个常见的问题,但通过正确的字符编码设置和编码转换方法,可以有效地解决乱码问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【Python】中文乱码问题与解决方案 深入分析](https://blog.csdn.net/Xuange_Aha/article/details/130441906)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值