首頁  >  文章  >  後端開發  >  python中文亂碼問題大總結

python中文亂碼問題大總結

高洛峰
高洛峰原創
2016-10-19 16:09:291371瀏覽

在運行這樣類似的程式碼:

#!/usr/bin/env python
s="中文"
print s

   


最近常遇到這樣的問題:

最近常遇到這樣的問題:

問題一:SyntaxError: Non-ASC ondformer 3, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

問題二:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 intenot 108: 108 in range(128)

問題三:UnicodeEncodeError: 'gb2312' codec can't encode character u'u2014' in position 72366: illegal multibyte sequence

弄不出來,找了很多方案,這裡有些是我前幾天找到的一些方案,拿出來給大家分享一下哈

  字符串在Python內部的表示是unicode 編碼,因此,在做編碼轉換時,通常需要以unicode作為中間編碼,也就是先將其他編碼的字串解碼(decode)成unicode,再從unicode編碼(encode)成另一種編碼。

decode的作用是將其他編碼的字串轉換成unicode編碼,如str1.decode('gb2312'),表示將gb2312編碼的字串str1轉換成unicode編碼。

encode的作用是將unicode編碼轉換成其他編碼的字串,如str2.encode('gb2312'),表示將unicode編碼的字串str2轉換成gb2312編碼。

在某些IDE中,字串的輸出總是出現亂碼,甚至錯誤,其實是由於IDE的結果輸出控制臺本身不能顯示字串的編碼,而不是程式本身的問題。

如在UliPad中運行以下程式碼:

s=u"中文"

print s

會提示:UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: 28 )。這是因為UliPad在英文WindowsXP 上的控制台訊息輸出視窗是按照ascii編碼輸出的(英文系統的預設編碼是ascii),而上面程式碼中的字串是Unicode編碼的,所以輸出時產生了錯誤。

將最後一句改為:print s.encode('gb2312')

則能正確輸出「中文」這兩個字。

若最後一句改為:print s.encode('utf8')

則輸出:xe4xb8xadxe6x96x87,這是控制台資訊輸出視窗依照ascii編碼輸出utf8編碼的字串的結果。

下面程式碼可能比較通用一些,如下:

#!/usr/bin/env python  
#coding=utf-8  
s="中文"
if isinstance(s, unicode): 
    #s=u"中文"  
    print s.encode('gb2312') 
else: 
    #s="中文"  
    print s.decode('utf-8').encode('gb2312')
#!/usr/bin/env python
#coding=utf-8
s="中文"
if isinstance(s, unicode):
 #s=u"中文"
 print s.encode('gb2312')
else:
 #s="中文"
 print s.decode('utf-8').encode('gb2312')

   

看看下面一段程式碼:

#!/usr/bin/env python  
#coding=utf-8  
#python version:2.7.4 
#system:windows xp 
   
import httplib2
def getPageContent(url):
    '''''
    使用httplib2用编程的方式根据url获取网页内容
    将bytes形式的内容转换成utf-8的字符串
    '''
    #使用ie9的user-agent,如果不设置user-agent将会得到403禁止访问 
    headers={'user-agent':'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
            'cache-control':'no-cache'}
    if url:
         response,content = httplib2.Http().request(url,headers=headers)
            
         if response.status == 200 :
            return content

import sys  
reload(sys)  
sys.setdefaultencoding('utf-8')   #修改默认编码方式,默认为ascci 
print sys.getdefaultencoding()
   
content = getPageContent("http://www.oschina.net/")
print content.decode('utf-8').encode('gb2312')
#!/usr/bin/env python
#coding=utf-8
#python version:2.7.4
#system:windows xp
import httplib2
def getPageContent(url):
    '''
    使用httplib2用编程的方式根据url获取网页内容
    将bytes形式的内容转换成utf-8的字符串
    '''
    #使用ie9的user-agent,如果不设置user-agent将会得到403禁止访问
    headers={'user-agent':'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
            'cache-control':'no-cache'}
    if url:
         response,content = httplib2.Http().request(url,headers=headers)
          
         if response.status == 200 :
            return content

   


上面的程式碼的意思:向www.oschina.net網站請求他的主頁,(如果直接是utf-8編碼,不能輸出中文)想將編碼方式為utf-8轉向gd2312,出現問題三


當我把它將print content.decode('utf-8').encode('gb2312')改成print content.decode('utf-8').encode('gb2312', 'ignore')時,OK了,可以顯示中文了,但不敢確定是否為全部,貌似只有部分吧,有些不能用gb2312編碼

然而,當我把網站換成www.soso.com時,不用轉為gb2312,用utf-8即可正常顯示中文

總結一下:

  向文件直接輸出ss會拋出同樣的異常。在處理unicode中文字串的時候,必須先對它呼叫encode函數,轉換成其它編碼輸出。這一點對各個環境都一樣。在Python中,「str」物件就是一個位元組數組,至於裡面的內容是不是一個合法的字串,以及這個字串採用什麼編碼(gbk, utf-8, unicode)都不重要。這些內容需要使用者自己記錄和判斷。這些的限制也同樣適用於「unicode」物件。要記住「unicode」物件中的內容可絕對不一定就是合法的unicode字串,我們很快就會看到這種情況。在windows的控制台上,支援gbk編碼的str物件和unicode編碼的unicode物件。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn