Python轉碼問題的解決方法——illegal multibyte sequence
阿新 • • 發佈:2019-02-13
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]])