事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为Unicode转换格式,即UTF(Unicode Transformation Format)。常见的UTF格式有:UTF-7, UTF-7.5, UTF-8,UTF-16, 以及 UTF-32。
#-*-coding:utf-8-*-
s='中文'
print type(s) #查看s的字符类型
print s
s.decode('utf8') #解码utf8,默认的编码方式是unicode
s.decode('gbk', "ignore") #解码utf8,忽略其中有异常的编码,仅显示有效的编码
s.decode('gbk', 'replace')
print type(s)
print s
s.encode('gb2312') ##编码为utf8
print type(s)
print s
test.py编码必需与s.decode('utf8')指定的编码一致,不然会抛出解码异常信息,可以通过s.decode("gbk", "ignore")或s.decode("gbk", "replace")来解决。
s.decode("utf-8", "replace") 替换其中异常的编码,这个相对来可能一眼就知道那些字符编码出问题了。
所以python3中str类型已经没有decode方法,例如:
s = "python"
s.decode('gbk', "ignore")
AttributeError Traceback (most recent call last)
in ()
1 s = "python"
----> 2 s.decode('gbk', "ignore")
AttributeError: 'str' object has no attribute 'decode'
此外,我们可以用dir(s)查看有无此方法。
有几点需要注意:
1:字符串通过编码转换为字节码,字节码通过解码转换为字符串
str--->(encode)--->bytes,bytes--->(decode)--->str
import sys
import chardet
print('目前系统的编码为:',sys.getdefaultencoding())
name='小明'
print(type(name))#首先我们来打印下转码前的name类型,因为它是str,所以可以通过encode来进行编码
目前系统的编码为: utf-8
{'encoding': 'utf-8', 'language': '', 'confidence': 0.7525}
b'\xe5\xb0\x8f\xe6\x98\x8e'
可以看到name的type:str类型通过encode('utf-8')转换成了bytes类型从unicode转str,被看做是把一个信息文本编码为二进制字节流的过程,要用encode方法
name2=name1.decode('utf-8')
print(type(name2))
print(name2)
小明
这里要跟大家说下,decode()括号中为什么写utf-8,而不写gbk,可以这样理解,因为要解码,你总得告诉它我是什么编码的吧,比如我原先是utf-8格式的编码,现在要解码,但是如果冒充utf-8,说自己是gbk,那就会出现乱码,见下:
name = "小明"
name1=name.encode('utf-8')
name2=name1.decode('utf-8')
name3=name2.encode('gbk')
name4=name3.decode('gbk')
print("name:")
print(type(name))
print(name)
print("name1:")
print(type(name1))
print(name1)
print("name2:")
print(type(name2))
print(name2)
print("name3:")
print(type(name3))
print(name3)
print("name4:")
print(type(name4))
print(name4)
name:
小明
name1:
b'\xe5\xb0\x8f\xe6\x98\x8e'
name2:
小明
name3:
b'\xd0\xa1\xc3\xf7'
name4:
小明
所以不难看出,其实utf-8和gbk之间都是通过unicode来做一个中间转换的操作
import urllib.request
res=urllib.request.urlopen('http://www.baidu.com')
htmlBytes=res.read()
print(type(htmlBytes))
htmlStr = htmlBytes.decode('utf-8')
print(htmlBytes)
b'\n\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t\r\n \r\n\t\t\t \r\n\t\r\n\t\t\t \r\n\t\r\n\t\t\t \r\n\t\r\n\t\t\t \r\n\t\t\t \r\n\r\n\t\r\n
htmlBytes为bytes类型所以可通过decode方法解码为str类型
htmlStr
'\n\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t\r\n \r\n\t\t\t \r\n\t\r\n\t\t\t \r\n\t\r\n\t\t\t \r\n\t\r\n\t\t\t \r\n\t\t\t \r\n\r\n\t\r\n \r\n\t\t\t \r\n\t\r\n\t\t\t \r\n\t\r\n\t\t\t \r\n\t\r\n\t\t\t \r\n\t\t\t
print(htmlStr)