最近開始復習Python爬蟲,使用了VS Code作為編輯器,配置了Task輸出的時候,發現VS Code的Output對於中文是亂碼,而上網查到的資料是Output默認輸出UTF-8格式,而且程序在Windows控制台運行中文正常輸出。這個問題也就沒有不了了之。
后來又開始爬取網頁,以baidu為例,但是運行data.decode("UTF-8")
的時候,出現下面的錯誤:
line 19, in <module>
data = data.decode("UTF-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
我感到很奇怪,因為無論是chardet
查看的網頁編碼,還是查看baidu的源代碼,都是顯示UTF-8,按照道理不應該出現這些錯誤。通過查找資料發現,是Python輸出的編碼問題,這里對使用爬蟲過程中遇到的關於編碼的問題進行記錄。
系統環境:Windows 10,Python 3.5.1
1. 查看網頁編碼
獲取的網頁需要知道它的編碼,以便后續進行處理。通常有以下幾種方法:
- 查看網頁的META字段,看它使用的是什么編碼。
- 根據服務器返回的
HEADER
里的charset
變量獲取。
但是這種方式不一定能夠保證准確,這里使用第三方庫chardet
。
import urllib.request
import chardet
url = "http://www.baidu.com"
data = urllib.request.urlopen(url).read()
print(chardet.detect(data))
運行結果為:{'confidence': 0.99, 'encoding': 'utf-8'}
2. 輸出網頁中文亂碼
這里使用的是VS Code,默認情況下,VS Code的Output輸出應該是UTF-8編碼,但是輸出的中文仍然是亂碼。而且有的時候(很奇怪不是每次),運行data.decode("UTF-8")
會出現下面的錯誤:
line 19, in <module>
data = data.decode("UTF-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
網上搜索這個問題,發現是Windows下Python3的print()函數的問題,需要修改默認輸出的編碼:
import io
import sys
import urllib.request
import chardet
#改變標准輸出的默認編碼
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8')
print("中文???!!@")
url = "http://www.baidu.com"
data = urllib.request.urlopen(url).read()
print(chardet.detect(data))
data = data.decode("UTF-8")
print(data)
這樣不僅可以正常解碼(decode),而且在VS Code中輸出的中文亂碼問題也得到的解決。