windows python 打印utf-8亂碼


從網上抓了一些字節流,想打印出來結果發生了一下錯誤:

UnicodeEncodeError: 'gbk' codec can't encode character '\xbb' in position 8530: illegal multibyte sequence

代碼

 

[python]  view plain copy
 
  1. import urllib.request  
  2. res=urllib.request.urlopen('http://www.baidu.com')  
  3. htmlBytes=res.read()  
  4. print(htmlBytes.decode('utf-8'))  


錯誤信息讓人很困惑,為什么用的是'utf-8'解碼,錯誤信息卻提示'gbk'錯誤呢?

 

不僅如此,從百度首頁的html中發現以下代碼:

 

[html]  view plain copy
 
  1. <meta http-equiv="content-type" content="text/html;charset=utf-8">  


這說明網頁的確用的是utf-8,為什么會出現Error呢?

 

在python3里,有幾點關於編碼的常識

1.字符就是unicode字符,字符串就是unicode字符數組

如果用以下代碼測試,

 

[python]  view plain copy
 
  1. print('a'=='\u0061')  


會發現結果為True,足以說明兩者的等價關系。

 

2.str轉bytes叫encode,bytes轉str叫decode,如上面的代碼就是將抓到的字節流給decode成unicode數組

我根據上面的錯誤信息分析了字節流中出現\xbb的地方,發現有個\xc2\xbb的特殊字符»,我懷疑是它無法被解碼。

用以下代碼測試后

 

[python]  view plain copy
 
  1. print(b'\xc2\xbb'.decode('utf-8'))  

它果然報錯了:UnicodeEncodeError: 'gbk' codec can't encode character '\xbb' in position 0: illegal multibyte sequence

 

上網找了下utf-8編碼表,發現的確特殊字符»的utf-8形式就是c2bb,unicode是'\u00bb',為什么無法解碼呢。。。

仔細看看錯誤信息,它提示'gbk'無法encode,但是我的代碼是utf-8無法decode,壓根牛頭不對馬嘴,終於讓我懷疑是print函數出錯了。。於是立即有了以下的測試

 

[python]  view plain copy
 
  1. print('\u00bb')  

結果報錯了:UnicodeEncodeError: 'gbk' codec can't encode character '\xbb' in position 0: illegal multibyte sequence

 

原來是print()函數自身有限制,不能完全打印所有的unicode字符。

知道原因后,google了一下解決方法,其實print()函數的局限就是Python默認編碼的局限,因為系統是win7的,python的默認編碼不是'utf-8',改一下python的默認編碼成'utf-8'就行了

 

[python]  view plain copy
 
  1. import io  
  2. import sys  
  3. import urllib.request  
  4. sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8')<span style="white-space:pre">    </span>#改變標准輸出的默認編碼  
  5. res=urllib.request.urlopen('http://www.baidu.com')  
  6. htmlBytes=res.read()  
  7. print(htmlBytes.decode('utf-8'))  

 

運行后不報錯了,但是居然有好多亂碼(英文顯示正常,中文則顯示亂碼)!!又一陣折騰后發現是控制台的問題,具體來說就是我在cmd下運行該腳本會有亂碼,而在IDLE下運行卻很正常。

由此我推測是cmd不能很好地兼容utf8,而IDLE就可以,甚至在IDLE下運行,連“改變標准輸出的默認編碼”都不用,因為它默認就是utf8。如果一定要在cmd下運行,那就改一下編碼,比如我換成“gb18030”,就能正常顯示了:

 

[python]  view plain copy
 
  1. sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')         #改變標准輸出的默認編碼  

最后,附上一些常用的和中文有關的編碼的名稱,分別賦值給encoding,就可以看到不同的效果了:

 

 

編碼名稱 用途
utf8 所有語言
gbk 簡體中文
gb2312 簡體中文
gb18030 簡體中文
big5 繁體中文
big5hkscs 繁體中文


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM