环境配置:
windows 10, 64bit
Anaconda 3, python 3.7
1、问题描述:
如上图所示,我们从python爬虫得到网页内容,print(req.text)可能会出现中文乱码,其中,req是我们获取到的response,如:req = requests.get(url)。在网上找了挺多方法都不起作用。下面,将通过三种方法来分别解决中文乱码问题。
2、问题分析:
运行以下python代码:
print(req.encoding)
print(req.apparent_encoding)
print(requests.utils.get_encodings_from_content(req.text))
(1)“print(req.encoding)”返回的是python爬虫爬取到的网页源码response的编码。
(2)我们知道Requests 会基于 HTTP 头部对响应的编码作出有根据的推测,这个一般跟原HTML文件中设置的编码有关。当你访问 req.text 之时,Requests 会使用其推测的文本编码来作为req.text的编码。所以“print(req.apparent_encoding)”获取的是Requests 推测的文本编码。
(3)“print(requests.utils.get_encodings_from_content(req.text))”获取的是原html网页文件中设置的编码,如下所示:
上面代码的运行结果如下:
ISO-8859-1 # response的编码
GB2312 # Requests推断出来的编码,即req.text的编码
['GB2312'] # 原HTML文件中设置的编码,即charset = "GB2312"
问题原因:
response的编码为“ISO-8859-1”,而req.text的编码却用的是Requests推断的编码为“GB2312”,所以当我们print(req.text)就会出现乱码了。
3、解决方法:
根据以上原因,我们知道只需要让response的编码和req.text的编码保持一致就可以解决该问题。因此我们有以下三种解决办法:
(1)把response的编码改成原HTML文件的编码,因为Requests推断的编码(即req.text的编码)一般是跟原HTML文件的编码保持一致或者是互相兼容的。代码如下:
req.encoding = "GB2312"
(2)把response的编码改成Requests推断的编码(即req.text的编码)。代码如下:
req.encoding = req.apparent_encoding
(3)通过编码、解码的方式,先把req.text编码成response的编码,然后再解码成python默认的编码。代码如下:
html = req.text.encode('ISO-8859-1').decode('GB2312')
最后“.decode('GB2312')”这个参数填的是“GB2312”,但是 req.text.encode('ISO-8859-1')分明是把req.text.编码成“ISO-8859-1”了,通过
import chardet
print(chardet.detect(req.text.encode('ISO-8859-1')))
查看,得到的是 req.text.encode('ISO-8859-1')的编码为“GB2312”,这可能是python直接把它转成“GB2312”编码了,所以后面是“.decode("GB2312")”来解码成我们python设置的默认编码“utf-8”。
通过以上的三种方法都可以解决python爬虫的中文乱码问题。