杰瑞科技汇

Python requests 如何处理中文?

  1. 发送请求时处理中文:如何正确地在 URL、请求头、请求体(如表单数据)中包含中文字符。
  2. 接收响应时处理中文:如何正确地解析服务器返回的、包含中文的响应内容(如 HTML、JSON)。

准备工作:安装 requests

如果你还没有安装 requests 库,请先通过 pip 安装:

Python requests 如何处理中文?-图1
(图片来源网络,侵删)
pip install requests

发送请求时处理中文

这是最常见的场景,尤其是在 GET 请求的 URL 参数和 POST 请求的表单数据中。

核心原则:正确编码

当你在 URL 或请求体中包含非 ASCII 字符(如中文)时,必须将它们转换为一种网络可以传输的格式,这个过程叫做 URL 编码(或百分号编码),空格会变成 %20, 会变成 %23

requests 库在大多数情况下能自动帮你处理,但你需要确保你提供的是 Unicode 字符串(在 Python 3 中,所有字符串默认都是 Unicode)。

GET 请求中的中文 URL 参数

错误的做法:直接拼接

直接拼接中文字符串到 URL 中,可能会导致请求失败或接收到错误的结果。

import requests
# 错误示例:直接拼接中文字符
keyword = "北京"
url = f"https://www.baidu.com/s?wd={keyword}"
# 这种写法在某些系统上可能工作,但非常不可靠,因为中文没有经过编码
response = requests.get(url)
# response.text 可能会是乱码,或者请求根本发不出去

正确的做法:使用 params 参数

requests.get()params 参数会自动帮你将字典中的键值对进行 URL 编码,这是最推荐、最安全的方式。

import requests
keyword = "北京"
# 使用 params 字典,requests 会自动处理编码
url = "https://www.baidu.com/s"
params = {
    "wd": keyword,
    "ie": "utf-8"  # 告诉百度使用 UTF-8 编码
}
response = requests.get(url, params=params)
# 检查响应状态码
response.raise_for_status() 
# 查看最终的、编码后的 URL
print("请求的 URL:", response.url) 
# 输出: 请求的 URL: https://www.baidu.com/s?wd=%E5%8C%97%E4%BA%AC&ie=utf-8
# 你可以看到 "北京" 被编码成了 %E5%8C%97%E4%BA%AC

POST 请求中的中文表单数据

同样,在发送 POST 请求时,如果表单数据包含中文,也应该让 requests 自动处理。

import requests
url = "http://httpbin.org/post" # 一个用于测试的网站
data = {
    "username": "张三",
    "city": "上海",
    "comment": "你好,世界!"
}
# requests 会自动将 data 字典编码并放到请求体中
response = requests.post(url, data=data)
print(response.json()) # httpbin.org 会返回你发送的数据,可以验证是否正确

接收响应时处理中文

服务器返回的数据(响应体)也可能包含中文,你需要确保在读取内容时使用正确的字符编码。

核心原则:正确解码

服务器通常会在响应头中通过 Content-Type 字段告诉客户端它使用了什么编码,Content-Type: text/html; charset=utf-8

requests 库会尝试自动从响应头中解析 charset,如果找不到,它会使用一些启发式方法(如 chardet 库)来猜测编码,这个过程是自动的,但有时可能会猜错。

如何确保正确解码?

使用 response.text (推荐)

response.text 属性会自动将响应内容解码成 Unicode 字符串,在绝大多数情况下,你只需要直接使用它即可。

import requests
url = "https://www.baidu.com/s?wd=北京"
response = requests.get(url)
# response.text 会自动根据响应头的 charset 进行解码
# 你可以直接打印,它会自动处理成可读的中文
print(response.text[:100]) # 打印前 100 个字符

使用 response.contentresponse.encoding (更精确)

如果你怀疑 requests 自动解码出了问题,或者你想手动控制解码过程,可以使用 response.contentresponse.encoding

  • response.content: 返回的是原始的二进制字节流 (bytes)。
  • response.encoding: 获取或设置响应的编码。
import requests
url = "https://www.baidu.com/s?wd=北京"
response = requests.get(url)
# 方法一:检查并手动设置编码(如果自动解码失败)
# 先看看 requests 自动猜的编码是什么
print("自动检测的编码:", response.encoding) # 通常是 'utf-8'
# 如果发现是乱码,可以手动设置正确的编码
# response.encoding = 'gbk' # 有些老旧网站可能用 GBK
# 然后再使用 .text
print(response.text[:100])
# 方法二:直接用 .content 手动解码
# 这在你明确知道编码,或者 .text 乱码时非常有用
html_bytes = response.content
# 手动解码,例如用 'utf-8'
html_str = html_bytes.decode('utf-8')
print(html_str[:100])

处理 JSON 响应

如果服务器返回的是 JSON 数据,并且其中包含中文,requestsjson() 方法会完美处理。

import requests
import json # json 库本身也支持处理中文
url = "https://api.github.com/repos/python/cpython" # GitHub API
response = requests.get(url)
# .json() 方法会自动解码内容并解析成 Python 字典
repo_data = response.json()
# 直接访问包含中文的字段(如 description)
# GitHub API 的响应通常是 UTF-8 编码
description = repo_data.get('description', '')
print(description)

总结与最佳实践

场景 推荐方法 原因
GET 请求带中文参数 使用 requests.get(url, params={'key': '中文'}) params 会自动进行 URL 编码,安全可靠。
POST 请求带中文数据 使用 requests.post(url, data={'key': '中文'}) data 会自动编码并设置正确的 Content-Type
读取响应中的中文 直接使用 response.text requests 会自动根据响应头解码,最方便。
响应解码失败时 检查并设置 response.encoding
使用 response.content.decode('正确的编码')
手动干预,解决自动解码可能出错的问题。
处理 JSON 中的中文 使用 response.json() json() 方法会正确处理 Unicode 字符。

黄金法则

  1. 发送时:始终让 requests 通过 paramsdata 参数来处理编码,不要手动拼接。
  2. 接收时:优先使用 response.text,如果遇到乱码,再考虑手动设置 response.encoding 或使用 response.content 进行解码。
分享:
扫描分享到社交APP
上一篇
下一篇