Python中讀取txt文本出現“ 'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence”的解決辦法


UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence

今天練習通過讀取英文版的Walden.txt的文本信息,統計文本中的英文單詞詞頻的時候出現了這樣的錯誤提示。

錯誤的意思是:Unicode的解碼(Decode)出現錯誤了,以gbk編碼的方式去解碼(該字符串變成Unicode),但是此處通過gbk的方式,卻無法解碼(can't decode).''illegal multibyte sequence"的意思是非法的多字節序列,也就是說無法解碼了。

出現這樣的錯誤,可能是要處理的字符串本身不是gbk編碼,卻是以gbk編碼去解碼。比如,字符串本身是utf-8的,但用gbk去解碼,必然出錯。

針對以上的這個問題,查閱網上資料,可以按照如下的步驟進行嘗試:

(1)在打開文本時候,可以指明打開方式:

file = open(path, encoding='gbk')

(2)如果上一步還不能解決,可能是文本中出現的一些特殊符號超出了gbk的編碼范圍,可以選擇編碼范圍更廣的‘gb18030’,如:

 file = open(path, encoding='gb18030'

(3)如果(2)還不能解決,說明文中出現了連‘gb18030'也無法編碼的字符,可以使用‘ignore’屬性忽略非法字符,如:

file = open(path, encoding='gb18030', errors='ignore')

或者:

file=open(path).read().decode(‘gb18030’,’ignore’)

通過嘗試,基本解決問題,源代碼如下:

path = 'E://Python/Walden.txt'
file = open(path,encoding = 'gb18030',errors = 'ignore')
file2 = open('E://Python/Walden2.txt','w')
file2.write(file.read())
file.close()
file2.close()
with open('E://Python/Walden2.txt','r') as text:
    words = text.read().split()
    print(words)
    for word in words:
        print('{}-{} times'.format(word,words.count(word)))

結果如圖:

雖然已經能夠區分各個單詞,但還有一定的問題,如大小寫重復統計,字符-的統計,還需要進一步改進。

 

總結:

Python文件讀寫的幾種模式:

  r, rb ,w ,wb 那么在讀寫文件時,有無b標識的主要區別在哪里呢?

1.文件使用方式標識

   ‘r’: 默認值,表示從文件讀取數據。

   ‘w’: 表示要向文件寫入數據,並截斷從前的內容

    ‘a’:表示要向文件寫入數據,添加到當前內容尾部

    ‘r+’ :表示對文件進行可讀寫操作(刪除以前的所有數據)

    ‘r+a’:表示對文件可進行讀寫操作(添加到當前文件尾部)

    ‘b’:表示要讀寫二進制數據

2.讀文件

    進行讀文件操作時,直到讀到文檔結束符(EOF)才算讀取到文件最后,Python會認為字節\x1A(26)轉換成的字符為文檔結束符(EOF),故使用‘r’進行讀取二進制文件時,可能會出現文檔讀取不全的現象。

   例如:二進制文件中存在如下從低位向高位排列的數據:7F 32 1A 2F 3D 2C 12 2E 76

             如果使用‘r’進行讀取,則讀到第三個字節,即認為文件結束。

             如果使用‘rb’按照二進制位進行讀取的,不會將讀取的字節轉換成字符,從而避免了上面的錯誤。

   解決方案:  二進制文件就用二進制方法讀取‘rb’

   總結:

          使用‘r’的時候,如果碰到‘0x1A’,就視為文件結束,就是EOF。使用‘rb’則不存在這個問題,即:如果你用二進制寫入再用文件讀出的話,如果其中存在‘0x1A’,就只會讀出文件的一部分,使用‘rb’會一直讀取文件末尾。

3.寫文件

      對於字符串x='abc\ndef',我們可用len(x)得到它的長度為7,\n我們稱之為換行符,實際上就是0x0A。當我們用‘w’即文本方式寫的時候,在windows平台上會自動將‘0x0A’變成兩個字符‘0x0D’,'0x0A',即文件長度實際上變成8。當用‘r’文本方式讀取時,又自動的轉換成原來的換行符。如果換成‘wb’二進制方式來寫的話,則會保持一個字符不變,讀取的時候也是原樣讀取。所以如果用文本方式寫入,用二進制方式讀取的話,就要考慮這多出的一個字節了。‘0x0D’也稱回車符。Linux下不會變,因為Linux只使用‘0x0A’來表示換行。


免責聲明!

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



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