如何用Python requests.get()正确编码URL参数中的特殊字符?
问题描述
在Python 3.10的Jupyter Notebook中使用requests.get()抓取某ASP搜索引擎内容时遇到编码问题:
- 浏览器搜索栏输入
α时,URL末尾为?search=%u03B1,可正确返回α的搜索结果 - 运行以下代码调用
search('α'),返回的却是繁体中文“帢”的结果:
import requests def search(keyword): url = "xxxxxxxxxxx.asp" params = { 'search': keyword } # 注:原代码存在变量名错误,已修正为keyword headers = { ... } res = requests.get(url, params=params, headers=headers) return res.content
- 尝试传入
search("%u03B1"),返回的是字符串%u03B1的搜索结果,而非α的结果。
已尝试的情况:
输入(params) | 实际生成的URL | 搜索结果(res.content) |
|---|---|---|
α | ?search=%CE%B1 | 包含帢的内容 |
β | ?search=%CE%B2 | 包含帣的内容 |
γ | ?search=%CE%B3 | 包含帠的内容 |
%u03B1 | ?search=%25u03B1 | 包含%u03B1的内容 |
期望效果:
| 网站搜索栏输入 | 浏览器显示的URL | 浏览器搜索结果 |
|---|---|---|
α | ?search=%u03B1 | 包含α的内容 |
β | ?search=%u03B2 | 包含β的内容 |
γ | ?search=%u03B3 | 包含γ的内容 |
原因分析
- 编码格式不匹配:
requests库默认使用UTF-8编码生成URL参数,比如α会被编码为%CE%B1(UTF-8字节值)- 目标网站的ASP后端期望的是JavaScript风格的Unicode码点编码(
%uXXXX格式),其中%u03B1对应α的Unicode码点U+03B1
- 后端解码逻辑:网站后端将
%CE%B1按GBK/GB2312编码解码,得到了繁体中文“帢”(GBK中0xCEB1对应的字符)
解决方案
绕过requests的自动参数编码,手动将关键词转换为%uXXXX格式后拼接URL:
import requests def search(keyword): url = "xxxxxxxxxxx.asp" # 将每个字符转换为%uXXXX格式的Unicode码点编码 encoded_keyword = ''.join(f'%u{ord(char):04X}' for char in keyword) # 手动拼接完整URL,避免requests自动编码参数 full_url = f"{url}?search={encoded_keyword}" headers = { ... } # 保留你原有的请求头(比如User-Agent等) res = requests.get(full_url, headers=headers) return res.content # 调用测试 search('α')
代码说明:
ord(char)获取字符的Unicode码点(比如ord('α')返回945,即十六进制的03B1)f'%u{ord(char):04X}'将码点格式化为4位十六进制的%uXXXX字符串- 直接拼接URL而非使用
params参数,避免requests对参数进行UTF-8编码
补充验证
如果需要处理多字符关键词(比如αβ),上述代码会自动生成%u03B1%u03B2,和浏览器生成的URL格式一致,可正确返回对应结果。
内容的提问来源于stack exchange,提问作者Warren Chen
相关产品推荐
相关产品推荐

