1. 程式人生 > >python程式設計中中文輸出亂碼UnicodeEncodeError: 'ascii' codec can't encode character解決方案

python程式設計中中文輸出亂碼UnicodeEncodeError: 'ascii' codec can't encode character解決方案

問題是這樣的

我用的jupyter,下圖是我的原始碼我知道由於未把ASCII轉為utf8,但是我按照網上的程式碼修改後直接沒有output了
我加上
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
還是沒反應
 
 
 

百度了好久,有人提供了個解決方案是這樣的,因為按程式碼邏輯沒有問題,首先requests 得到的結果已經用utf-8來進行編碼了,但是beautifulSoup函式再次將目標用utf-8再次進行強轉,導致瞭如下的情況:

'''我們想要使用的字串'''
target_str  =  '2017\xe5\xb9\xb402\xe6\x9c\x8816\xe6\x97\xa512:53'   '''兩次轉碼後的字串''' get_str  =  u '2017\xe5\xb9\xb402\xe6\x9c\x8816\xe6\x97\xa512:53' 歸根結底是兩個物件的類不同,但python不支援這兩種型別的強轉,個人想了個比較臨時的解決方案,算是個python打了個補丁,就是將字串轉成二進位制,再轉回字串,這樣就unicode就不用給他加上編碼方式再轉成二進位制字串了,加了如下兩個函式:
def  encode(s):      '''將字串轉成二進位制'''      return  ' ' .join([ bin ( ord (c)).replace( '0b' , '')  for  in  s])   def
  decode(s):      '''將二進位制轉換成字串'''      return  ' '.join([chr(i) for i in [int(b, 2) for b in s.split('  ')]])

修改後的程式碼如下,但還是報錯了如圖:

  一看錯誤型別就是典型的型別錯誤咯,多次測驗我發現了一個問題 

timeresource的型別是 unicode! 導致解碼的時候出了型別格式錯誤,就更不用說後面繼續呼叫strptime函數了,所以首先要做的是把timeresource轉換成str,

參考一篇部落格

Python2x中Str&Unicode 
接下來我們來討論Python2x中的Str和Unicode。 
首先我開啟Python2.7的編譯環境。輸入以下程式碼:

>>>a="中文"
>>>a
'\xd6\xd0\xce\xc4'
>>>type(a)
<type 'str'>

>>>b=a.decode('gbk')
>>>b
u'\u4e2d\u6587'
>>>type(b)
<type 'unicode'>

>>>a.decode('ascii')
<UnicodeDecodeError>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

可以看到在Python2.7shell中,我們輸入”中文“這兩個中文字元時,用瞭解釋器的預設編碼格式,在windows下即為GBK,所以我們看到的是上面第一個圖中的十六進位制表達。可以看到此時a的型別是str。 
當我們對str型別的a用”gbk“解碼後賦給變數b,可以b的型別是unicode,十六進位制的表示式類似上面第二個圖。 
但是我們用ASCII編碼去解碼卻得到DecodeError的結果。 
所以我們得到一個結論:[str].decode(str對應的編碼)=[unicode],並且用什麼碼編碼就用什麼碼解碼。

>>>c=b.encode('utf8')
>>>c
'\xe4\xb8\xad\xe6\x96\x87'
>>>type(c)
<type 'str'>
>>>print c
涓?枃
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

我們可以看到對unicode型別的變數b用utf8編碼後變成了str型別的c,它的底層十六進位制表達如上面的第三張圖。
當我們print c的時候就打印出來亂碼了,原因是此時的str變數c用的是utf8編碼,但是直譯器的編碼是gbk,相當於用gbk的編碼方式去解釋用utf8編碼的字串,自然打印出來的是亂碼。(而且,上面說過gbk是兩個位元組表示一箇中文字元,utf8是三個位元組表示一箇中文字元,所以打印出來是三個亂碼的字元) 
所以我們得到另一個結論:[unicode].encode(你想要的編碼方式)=[str],直譯器編碼方式要與字串的編碼方式一樣才能解出正確的字元。

所以修改後的程式如下: