1. 程式人生 > >Python轉碼問題的解決方法——illegal multibyte sequence

Python轉碼問題的解決方法——illegal multibyte sequence

1.錯誤提示“UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 305: ordinal not in range(128)”

(1)原始碼為:

# coding:utf-8

import pytesseract
from PIL import Image

# tesseract.exe的全路徑
pytesseract.pytesseract.tesseract_cmd = r"D:\Python2.7\tesseract\Tesseract-OCR\tesseract.exe"
# 想要開啟的檔案的全路徑
image = Image.open(r"D:\Program\01.png")

text = pytesseract.image_to_string(image)
# text = pytesseract.image_to_string(image, lang="chi_sim")

with open(r"C:\Users\HuangQi\Desktop\01.txt", "w") as fp:
    fp.write(text.decode("utf-8", "ignore"))
    print text

(2)出現的錯誤提示為:

D:\Python2.7\python.exe D:/PyCharm/dytt_spider/text.py
Traceback (most recent call last):
  File "D:/PyCharm/dytt_spider/text.py", line 18, in <module>
    fp.write(text.decode("utf-8", "ignore"))
  File "D:\Python2.7\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 305: ordinal not in range(128)

Process finished with exit code 1

(3)解決方案為:

在.py檔案的開頭加上如下程式碼:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

關於為什麼要reload(sys)?

因為這裡的import語句可能不是sys的第一次匯入語句,可能是第2、3次進行sys模組的import,這裡是一個對sys的引用,只能reload才能進行重新載入。

為什麼要重新載入,而直接引用過來則不能呼叫該函式?

因為setdefaultencoding()函式在被系統呼叫後被刪除了(所以如果不重新載入,在Pycharm中顯示setdefaultencoding()函式不存在),所以通過import引用進來時其實已經沒有了,所以必須reload一次sys模組,這樣setdefaultencoding()才會為可用,才能在程式碼裡修改直譯器當前的字元編

碼。

2. 在Python中,可以對String呼叫decode和encode方法來實現轉碼。

(1)比如,若要將某個String物件s從gbk內碼轉換為UTF-8,可以如下操作 
s.decode('gbk').encode('utf-8′) 

可是,在實際開發中,我發現,這種辦法經常會出現異常: 

UnicodeDecodeError: ‘gbk' codec can't decode bytes in position 30664-30665: illegal multibyte sequence 
這 是因為遇到了非法字元——尤其是在某些用C/C++編寫的程式中,全形空格往往有多種不同的實現方式,比如\xa3\xa0,或者\xa4\x57,這些 字元,看起來都是全形空格,但它們並不是“合法”的全形空格(真正的全形空格是\xa1\xa1),因此在轉碼的過程中出現了異常。 
這樣的問題很讓人頭疼,因為只要字串中出現了一個非法字元,整個字串——有時候,就是整篇文章——就都無法轉碼。 (2)解決辦法: 
s.decode('gbk', ‘ignore').encode('utf-8′) 
因為decode的函式原型是decode([encoding], [errors='strict']),可以用第二個引數控制錯誤處理的策略,預設的引數就是strict,代表遇到非法字元時丟擲異常; 
如果設定為ignore,則會忽略非法字元; 
如果設定為replace,則會用?取代非法字元; 
如果設定為xmlcharrefreplace,則使用XML的字元引用。 python文件 decode( [encoding[, errors]])