Python3解決UnicodeDecodeError: 'utf-8' codec can't decode byte..問題 終極解決方案
阿新 • • 發佈:2018-12-05
Python3解決UnicodeDecodeError: 'utf-8' codec can't decode byte..問題 終極解決方案
2017年10月06日 13:19:42 閱讀數:52021 標籤: python 更多
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/wang7807564/article/details/78164855
0x00 問題引出:
最近在做一個買房自動化分析Python指令碼,需要爬取網頁。
在使用urllib獲取reqest的response的時候,還要進行解碼。
見語句:
result = res.decode('utf-8')
- 1
當執行該語句的時候,會造成異常:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe5 in position 103339: invalid continuation byte
- 1
0x01 問題分析
該情況是由於出現了無法進行轉換的 二進位制資料 造成的,可以寫一個小的指令碼來判斷下,是整體的字符集引數選擇上出現了問題,還是出現了部分的無法轉換的二進位制塊:
#python3 #以讀入檔案為例: f = open("data.txt","rb")#二進位制格式讀檔案 while True: line = f.readline() if not line: break else: try: #print(line.decode('utf8')) line.decode('utf8') #為了暴露出錯誤,最好此處不print except: print(str(line))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
手寫了一段程式碼,可以通過這段程式碼的輸出來判斷哪裡出現了問題。
- 1.如果輸出的程式碼都是hex形式的,可能就是你選擇的解碼字符集出現了錯誤。 對於python2.7版本的來說,網上有使用這樣一種看上去很霸氣,其實很low的方式,來處理:
#coding=utf8
import sys
reload(sys)
sys.setdefaultxxxx("utf8")
- 1
- 2
- 3
- 4
其實,這可以看作是python2系列版本的小bug,需要自行重新設定一下預設的編碼字符集,如果還要這麼設定的話,decode()的引數還拿來幹嘛。
所以,在python3版本中,就已經取消了這個方法。
- 2.如果是字符集出現錯誤,建議多選擇幾種字符集測試一下: 選擇的經驗是: 如果是爬取到的網頁檔案,可以檢視網頁檔案的meta標籤下的charset屬性值。
例如:
<meta charset="UTF-8">
- 1
也可以使用notepad++開啟,檢視下右下角的部位,會指示該檔案是那種編碼。
- 3.有的情況,是這樣的,整個檔案是好的,如果用notepad++開啟後,能夠看到檔案是可以開啟的,似乎什麼問題都沒有發生過,但是,用python進行解碼的時候,卻會出現錯誤。
我們執行上面的測試指令碼,可以看到出現這樣的情況:
<li id="J_menuHistory" data-page="J_pageHistory">
<a><i class="icon-history"></i>播放歷史 \0xe5 </a>
- 1
- 2
當然,這段程式碼是我隨手寫的一個例子,這裡,可以注意看到這個0xe5,這是無法轉換出來的部分,這是不屬於編碼字符集中的部分。所以,在進行編碼轉換的時候,會報錯。
0x03 解決方法
- 修改字符集引數,一般這種情況出現得較多是在國標碼(GBK)和utf8之間選擇出現了問題。
- 出現異常報錯是由於設定了decode()方法的第二個引數errors為嚴格(strict)形式造成的,因為預設就是這個引數,將其更改為ignore等即可。例如:
line.decode("utf8","ignore")