最近开始复习Python爬虫,使用了VS Code作为编辑器,配置了Task输出的时候,发现VS Code的Output对于中文是乱码,而上网查到的资料是Output默认输出UTF-8格式,而且程序在Windows控制台运行中文正常输出。这个问题也就没有不了了之。
后来又开始爬取网页,以baidu为例,但是运行data.decode("UTF-8")的时候,出现下面的错误:
line 19, in
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
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中输出的中文乱码问题也得到的解决。
参考资料