python3 下中文報錯


https://blog.csdn.net/weiliu0626/article/details/8296282

https://blog.csdn.net/weixin_34198583/article/details/93631868

查看系統編碼

報錯的字符是一個Unicode字符,查了下發現是python3,只有str和Unicode兩種編碼,去查了python3的系統編碼:

>>> import sys
>>> sys.getdefaultencoding()
'utf-8'

系統編碼就是utf8, 所以再去設置什么系統編碼,文件開頭加上‘# coding=utf8’ 對我的問題是沒啥幫助;

查看輸入輸出編碼

既然不是系統編碼,而且前面輸出都沒有問題,所以可能也不是之前讀寫文件的編碼錯誤,可能是print的時候,也就是標准輸入輸出的時候編碼問題了;那么print的時候做了什么,用的是什么編碼呢?
我們已經知道在python3中,輸出的時候,會把str/Unicode 變成utf8的編碼;來看一下環境中的輸出編碼是什么:

>>> import sys 
>>> sys.stdout.encoding
'ANSI_X3.4-1968'

emmmm…..果然!!!居然是ansi…

更改編碼:

import io,sys
 
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8') # 改變標准輸出的默認編碼

沒錯,問題就在這了。  怎么改呢。  這是類UNIX系統的標准輸出編碼問題。

首先, 把/etc/sysconfig/i18n里面的編碼改成xxxx.UTF-8

主要/重點:

然后,在/etc/profile中加入一行。export LC_ALL="UTF-8"

重啟


 

結果出師不利,在將爬取到的商品標題print出來時,拋出錯誤:

  root@fb6e7c6fbe5c:/home/binss# python3 amazon_test.py
  Traceback (most recent call last):
  File "amazon_test.py", line 30, in
  print(s)
  UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-7: ordinal not in range(128)

Python2時代最怕就是這個UnicodeEncodeError,沒想到到了Python3,又見到它了。

查看第一個字符,發現為'\u8266',於是測試以下代碼:

  >>> print('\u8266')

果然報錯

  Traceback (most recent call last):
  File "", line 1, in
  UnicodeEncodeError: 'ascii' codec can't encode character '\u8266' in position 0: ordinal not in range(128)

嘗試了各種姿勢,結果還是沒能解決。

最后突發奇想,print不行,那我把其輸出到文件捏?

  >>> s = '\u8266'
  >>> with open('xxx.txt', mode='w') as pubilc_file:
  ... pubilc_file.write(s)

依然報錯

  Traceback (most recent call last):
  File "", line 2, in
  UnicodeEncodeError: 'ascii' codec can't encode character '\u8266' in position 0: ordinal not in range(128)

那換成二進制輸出呢?

  >>> s = '\u8266'.encode('utf-8')
  >>> with open('xxx.txt', mode='wb') as pubilc_file:
  ... pubilc_file.write(s)

竟然成功輸出了正確的字符——"艦"!這,難道是因為終端的stdout不支持utf-8輸出?

於是打印看看當前的stdout是啥

  root@fb6e7c6fbe5c:/home/binss# python3
  Python 3.5.1 (default, Dec 18 2015, 00:00:00)
  [GCC 4.8.4] on linux
  Type "help", "copyright", "credits" or "license" for more information.
  >>> import sys
  >>> sys.stdout
  <_io.TextIOWrapper name='' mode='w' encoding='ANSI_X3.4-1968'>
  >>>

這個ANSI_X3.4-1968的編碼是什么東西?怎么不是utf-8?以此為關鍵詞Google,終於搜到相關文章:

http://lab.knightstyle.info/私がpython3でunicodeencodeerrorなのはどう考えてもデフォルト文字/

大概意思就是如果要輸出utf-8,需要通過以下代碼將ANSI_X3.4-1968改為utf-8

  import sys
  import io
  sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

然后再次檢驗stdout是否為utf-8

  >>> sys.stdout
  <_io.TextIOWrapper name='' encoding='utf-8'>

之后就可以愉快地print了

  >>> print('\u8266')
 


免責聲明!

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



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