Python語言編碼問題詳細解讀。Unicode,assci,utf-8,gbk等編碼

1、系統默認的腳本文件編碼html

Python 默認腳本文件都是 ANSCII 編碼的,當文件 中有非 ANSCII 編碼範圍內的字符的時候就要使用"編碼指示"來修正。 一個module的定義中,若是.py文件中包含中文字符(嚴格的說是含有非anscii字符),則須要在第一行或第二行指定編碼聲明:python

# -*- coding=utf-8 -*-或者 #coding=utf-8 其餘的編碼如:gbk、gb2312也能夠; 不然會出現相似:SyntaxError: Non-ASCII character '/xe4' in file ChineseTest.py on line 1, but no encoding declared; see http://www.pytho for details這樣的異常信息;n.org/peps/pep-0263.htmlshell

命令查看腳本默認的編碼方式
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>>
網絡

2.2 python中的編碼與解碼函數

  先說一下python中的字符串類型,在python中有兩種字符串類型,分別是str和unicode,他們都是basestring的派生類;str類型是一個包含Characters represent (at least) 8-bit bytes的序列;unicode的每一個unit是一個unicode obj;因此:字體

len(u'中國')的值是2;len('ab')的值也是2;網站

  在str的文檔中有這樣的一句話:The string data type is also used to represent arrays of bytes, e.g., to hold data read from a file. 也就是說在讀取一個文件的內容,或者從網絡上讀取到內容時,保持的對象爲str類型;若是想把一個str轉換成特定編碼類型,須要把str轉爲Unicode,而後從unicode轉爲特定的編碼類型如:utf-八、gb2312等;google

2.2.1 print 語句解釋編碼問題編碼

print 是打印默認的編碼方式,至關於對任何對象encode編碼轉化成str對象。默認是gbk的編碼就是對Unicode進行自動的gbk編碼,再按照gbk編碼輸出。url

當print語句碰到一個unicode目標的時候,會用當前python shell環境的默認編碼格式首先對unicode對象進行encode(此時unicode對象已經變成了一個str對象了),而後再以默認編碼格式爲基礎,根據其包含的漢字和編碼的對應規則,把這個str對象解釋成中文並顯示出來。可是當print語句碰到的直接是個str目標的時候,就無論其從unicode轉到str時用的編碼格式是什麼,直接用默認編碼格式的對應規則來解釋成中文。因此,當unicode對象轉換成str時的編碼格式和print語句的默認編碼格式不一致的時候就會出現亂碼現象。好比在cmd的python shell裏面:

複製代碼
證實Python 系統默認編碼gbk
>>> s= '你好'
>>> s
'\xc4\xe3\xba\xc3'
>>> s = u'你好'
>>> s
u'\xc4\xe3\xba\xc3'
>>> s = '你好'
>>> s
'\xc4\xe3\xba\xc3'
>>> print type(s)
<type 'str'>
>>>unicode 編碼打印錯誤,print 解析字符串而不是Unicode 編碼
>>> s = u'你好'
>>> print s
ÄãºÃ
>>>uni = u'你好' #存入一個unicode對象 >>>print uni 你好 #能夠正常顯示 至關於Unicode.encode(gbk) >>>uni.encode("gbk") '\xc4\xe3\xba\xc3' #顯示的是個str對象了,若是type(uni.encode("gbk"))獲得的就是str對象 >>>print uni.encode("gbk") 你好 #能夠正常顯示,由於在cmd下的pythonshell裏默認個編碼格式就是gbk,gbk解析 >>>uni.encode("utf-8") '\xe4\xbd\xa0\xe5\xa5\xbd' #能夠看到,encode用的編碼格式不一樣,編成的字符串也是不一樣的 >>>print uni.encode("utf-8") 浣犲ソ #亂碼,由於用了gbk中漢字和字符串編碼格式對應規則去解釋了用utf-8編碼成的字符串。解釋的編碼格式不對應。 #######さらに###### >>>print '\xc4\xe3' #本身寫出來的這麼個字符串(前面不加r)的話也會被print解釋成中文,按照編碼格式輸出 你 >>>print uni.encode("utf-8").decode("gbk") 浣犲ソ ''' 亂碼,並且和上面的亂碼同樣,這是由於,在uni被utf-8 encode以後,這個對象變成了str對象,是'\xe4\xbd\xa0\xe5\xa5\xbd' 這個。 後來,它又被按照gbk的規則解碼,又變回了unicode,可是此時它在內存裏的二進制數據已經和最初的uni不同了。 最初的uni,應該是'\xc4\xe3\xba\xc3'.decode("gbk"),而如今的這個東西,他decode以前的字符串已經變過了。 這麼一個東西再拿去print,又把它編碼成了gbk格式,至關於前面那步decode沒有作,變回了'\xe4\xbd\xa0\xe5\xa5\xbd'。 再解釋成漢字,固然就和最開始用uni編碼成utf-8格式再解釋成漢字的亂碼同樣了 '''

 

2.2.2 腳本print 打印的正確方式

  上面已經證實了系統的默認編碼方式是gbk,就是print  最後正確的編碼方式應該是gbk

兩種解決編碼不匹配的狀況:

一是明確的指示出 s 的編碼方式
# -*- coding: utf-8 -*- 
s = '中文' 
s.decode('utf-8').encode('gb2312') 
二是更改 sys.defaultencoding 爲文件的編碼方式
#! /usr/bin/env python 
# -*- coding: utf-8 -*-
import sys 
reload(sys) # Python2.5 初始化後會刪除 sys.setdefaultencoding 這個方法,咱們須要從新載入 
sys.setdefaultencoding('utf-8')
str = '中文' 
str.encode('gb2312')

 

3、實踐經驗中爬取數據的得到

# -*- coding: utf-8 -*- 
'''
#加油兩個字能夠很好的比較編碼正確和錯誤
#### 錯誤的處理方式,
s = "中文"
print s
#這裏print就不是輸出gbk的編碼,是按照頭文件utf-8的格式輸出
# 結果:中文
print s.decode('utf-8')
#結果中文,s進行解碼稱爲Unicode,print打印就和系統print打印同樣自動將Unicode進行
#解碼,不用encode編碼也能輸出,可是最好轉化成爲字符串輸出。
上面實例就是錯誤使用編碼,錯誤使用編碼會出現個別字體的亂碼。
'''



'''
要點一、聲明頭文件# -*- coding: utf-8 -*- 說明全部的代碼和中文是utf-8的編碼方式
要點二、print輸出函數輸出到前臺cmd中的默認系統編碼方式是GBK,
要點三、儘可能將Unicode轉化成爲字符串str (gbk或者utf-8),再去處理。



#unicode 轉化成爲字符串
s = u'加油'
print s
#結果:加油。緣由:系統自動將Unicode升級gbk編碼成爲字符串,而後系統print 打印gbk
print s.encode('utf-8')
#結果:鍔犳補。錯誤緣由:Unicode 編碼成爲utf-8的字符串形式,可是print打印系統是gbk的,編碼衝突。
print s.encode('gbk')
#結果:加油。緣由:和print s等價,認爲編碼了gbk,系統打印
ss = "加油"
print ss
#結果:鍔犳補。緣由:ss爲utf-8的字符串str,print 打印的對應編碼字符串是gbk的,因此編碼衝突。
print ss.decode('utf-8').encode('gbk')
#結果:加油。緣由:ss首先從字符串編碼utf-8解碼成爲unicode,而後進行編碼gbk,等價使用print ss.decode('utf-8')。
'''



'''
3.1python中關於中文轉換url編碼的問題
爬蟲的時候咱們常常會碰到中文連接編碼出現變換的問題,
例如'麗江'中文在url的地址編碼倒是'%E4%B8%BD%E6%B1%9F',
所以需 要作一個轉換。這裏咱們就用到了模塊urllib。
'''
import urllib
data = '麗江'
print data.decode('utf-8').encode('gbk')
#對utf-8的中文編碼
print urllib.quote(data)
#那咱們想轉回去呢?
print urllib.unquote('%E4%B8%BD%E6%B1%9F').decode('utf-8').encode('gbk')

'''
'麗江'在網頁編碼是gbk的轉換碼是'%C0%F6%BD%AD',utf-8中的轉化碼是'%E4%B8%BD%E6%B1%9F',實際上是編碼問題。
百度的是gbk,其餘的通常網站好比google就是utf8的。因此能夠用下列語句實現。
'''

#江蘇課題的編碼轉化
import sys,urllib
s = '江蘇'
print urllib.quote(s.decode(sys.stdin.encoding).encode('gbk'))
print urllib.quote(s.decode(sys.stdin.encoding).encode('utf8'))

for place in ['南京','無錫','徐州','常州','蘇州','鹽城','南通','連雲港','淮安','鹽城','揚州']:
    print urllib.quote(place)
    

####################
#結果:
'''
>>> 
麗江
%E4%B8%BD%E6%B1%9F
麗江
%E4%B8%BD%E6%B1%9F
%E6%B6%93%E8%8A%A5%E7%9D%99
>>> 
'''

#############################333
相關文章
相關標籤/搜索