requests中文乱码问题

Talent is luck. The important thing in life is courage. ——《曼哈顿》

有天赋是运气,生活中更为重要的是要有勇气。

发现问题

在使用requests.get()去抓取网页时,发现中文乱码

1
2
3
4
5
import requests

url = 'https://salling.com.cn'
response = requests.get(url)
print(response.text)

大概是这个样子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<nav class="site-state">
<div class="site-state-item site-state-posts">
<a href="/archives/">

<span class="site-state-item-count">22</span>
<span class="site-state-item-name">日志</span>
</a>
</div>
<div class="site-state-item site-state-categories">
<a href="/categories/">

<span class="site-state-item-count">11</span>
<span class="site-state-item-name">分类</span></a>
</div>
<div class="site-state-item site-state-tags">
<a href="/tags/">

<span class="site-state-item-count">20</span>
<span class="site-state-item-name">标签</span></a>
</div>
</nav>

问题原因

  当调用 Response.text 方法时,Requests首先在Response Headers检测是否存在指定的编码方式,如果不存在,则会使用 charade 来尝试猜测编码方式。在请求的网站中,如果Response Headers中的Content-Type只指定了Type,没有指定charset类型,并且 Content-Type 头部字段包含 text 的值时Requests才不去猜测编码方式。在这种情况下,默认字符集为ISO-8859-1,也就出现了中文乱码现象,这时就需要我们去指定编码方式。

解决问题

一.手动指定编码

  可以通过查看网页源代码中head下的charset="XXX"来确定网页编码,如下:

1
2
3
4
5
6
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">

  很容易就发现网页的编码方式是UTF-8

1
2
3
4
5
6
import requests

url = 'https://salling.com.cn'
response = requests.get(url)
response.encoding = 'utf-8'
print(response.text)

  问题解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<nav class="site-state">
<div class="site-state-item site-state-posts">
<a href="/archives/">

<span class="site-state-item-count">22</span>
<span class="site-state-item-name">日志</span>
</a>
</div>
<div class="site-state-item site-state-categories">
<a href="/categories/">

<span class="site-state-item-count">11</span>
<span class="site-state-item-name">分类</span></a>
</div>
<div class="site-state-item site-state-tags">
<a href="/tags/">

<span class="site-state-item-count">20</span>
<span class="site-state-item-name">标签</span></a>
</div>
</nav>

二.apparent_encoding根据网页内容分析编码方式

1
2
3
4
5
6
import requests

url = 'https://salling.com.cn'
response = requests.get(url)
response.encoding = response.apparent_encoding
print(response.text)

  问题同样解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<nav class="site-state">
<div class="site-state-item site-state-posts">
<a href="/archives/">

<span class="site-state-item-count">22</span>
<span class="site-state-item-name">日志</span>
</a>
</div>
<div class="site-state-item site-state-categories">
<a href="/categories/">

<span class="site-state-item-count">11</span>
<span class="site-state-item-name">分类</span></a>
</div>
<div class="site-state-item site-state-tags">
<a href="/tags/">

<span class="site-state-item-count">20</span>
<span class="site-state-item-name">标签</span></a>
</div>
</nav>

PS: 这两种方式究竟哪种才是值得推荐的那?
欲知结果如何,请看下篇文章《Python装饰器之函数运行时间》