杰瑞科技汇

Python urlencode 中文如何正确编码?

urlencode 是 Python 标准库 urllib.parse 中的一个函数,主要用于将字典或元组序列格式的数据转换为 URL 查询字符串(key=value&key2=value2 的形式)。

Python urlencode 中文如何正确编码?-图1
(图片来源网络,侵删)

处理中文的核心问题在于字符编码,URL 只能包含 ASCII 字符,因此像中文这样的非 ASCII 字符必须进行编码(通常使用 UTF-8 编码),然后再转换成一种安全的格式,最常见的就是 Percent-encoding(也称为 URL 编码),即 字符 -> UTF-8 字节 -> %XX 的格式。

下面我们分步讲解,从基础到高级用法。

准备工作

你需要导入 urlencode 函数。

from urllib.parse import urlencode

基础用法:处理简单的中文键值对

假设你有一个包含中文的字典,你想把它转换成查询字符串。

Python urlencode 中文如何正确编码?-图2
(图片来源网络,侵删)
params = {
    'name': '张三',
    'city': '北京',
    'message': '你好,世界!'
}
# 直接使用 urlencode
query_string = urlencode(params)
print(query_string)

输出结果:

name=%E5%BC%A0%E4%B8%89&city=%E5%8C%97%E4%BA%AC&message=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81

解释:

  • urlencode 默认会使用 utf-8 编码对非 ASCII 字符进行转换。
  • 张三 被编码为 %E5%BC%A0%E4%B8%89
  • 北京 被编码为 %E5%8C%97%E4%BA%AC
  • 你好,世界! 被编码为 %E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81

这个结果可以直接拼接到 URL 的后面,http://example.com?name=%E5%BC%A0%E4%B8%89&...


高级用法:指定编码格式

虽然 utf-8 是目前最标准和推荐使用的编码,但有些老旧的系统可能仍然使用 gbkgb2312 编码,在这种情况下,你可以通过 encoding 参数来指定编码方式。

Python urlencode 中文如何正确编码?-图3
(图片来源网络,侵删)

示例:使用 GBK 编码

params = {
    'name': '张三',
    'city': '北京'
}
# 指定使用 gbk 编码
query_string_gbk = urlencode(params, encoding='gbk')
print(query_string_gbk)

输出结果:

name=%D5%C5%CA%A1&city=%B9%E3%D6%DD

解释:

  • 你可以看到,同样的汉字 "张三" 和 "北京",使用 gbk 编码后得到的 Percent-encoding 结果与 utf-8 完全不同。
  • 重要提示:除非目标服务器明确要求使用 gbk,否则强烈建议始终使用 utf-8,因为它能表示全球所有的字符。

进阶用法:处理列表类型的值

如果你的参数值是一个列表,urlencode 默认会将其转换为多个同名键的格式。

params_list = {
    'name': '李四',
    'hobbies': ['reading', '游泳', 'coding']
}
query_string_list = urlencode(params_list)
print(query_string_list)

输出结果:

name=%E6%9D%8E%E5%9B%9B&hobbies=reading&hobbies=%E6%B8%B8%E6%B3%B3&hobbies=coding

解释:

  • hobbies 列表中的每个元素都被转换,并形成了 hobbies=value1&hobbies=value2&... 的格式,这是标准的处理方式。

特殊用法:不自动编码(quote_via 参数)

有时候你可能想对使用不同的编码逻辑,或者想完全控制编码过程。urlencode 提供了 quote_via 参数,允许你传入一个自定义的编码函数。

默认情况下,它使用 quote_plus 函数,它会将空格编码为 号。

示例:使用 quote 代替 quote_plus

quote 函数会将空格编码为 %20,这在某些情况下更符合严格的 URL 标准。

from urllib.parse import quote
params = {
    'name': '王五',
    'query': 'this is a test'
}
# 使用 quote 函数,它会将空格编码为 %20
query_string_quote = urlencode(params, quote_via=quote)
print(query_string_quote)

输出结果:

name=%E7%8E%8B%E4%BA%94&query=this%20is%20a%20test

对比:如果使用默认的 quote_plus

query_string_quote_plus = urlencode(params) # 默认使用 quote_plus
print(query_string_quote_plus)

输出结果:

name=%E7%8E%8B%E4%BA%94&query=this+is+a+test

完整示例:构建带中文参数的 URL

这是一个更完整的例子,展示了如何将一个包含中文的字典转换为一个可以直接在浏览器中使用的完整 URL。

from urllib.parse import urlencode
# 1. 定义参数字典
search_params = {
    'q': 'Python 教程',
    'source': 'web',
    'page': 1
}
# 2. 使用 urlencode 生成查询字符串
# 我们使用 utf-8 编码,这是最推荐的做法
query_string = urlencode(search_params, encoding='utf-8')
# 3. 定义基础 URL
base_url = 'https://www.example.com/search'
# 4. 拼接成完整的 URL
full_url = f"{base_url}?{query_string}"
print("生成的查询字符串:")
print(query_string)
print("\n完整的 URL:")
print(full_url)

输出结果:

生成的查询字符串:
q=Python+%E6%95%99%E7%A8%8B&source=web&page=1
完整的 URL:
https://www.example.com/search?q=Python+%E6%95%99%E7%A8%8B&source=web&page=1

注意: 在这个例子中,"Python" 和 "教程" 之间的空格被编码成了 ,这是因为 urlencode 默认使用 quote_plus,如果你希望空格变成 %20,可以像下面这样修改:

from urllib.parse import quote
# ...
query_string = urlencode(search_params, encoding='utf-8', quote_via=quote)
# ...

这样 "Python 教程" 就会被编码为 Python%20%E6%95%99%E7%A8%8B

场景 方法 说明
基本中文处理 urlencode(params) 默认使用 utf-8 编码,空格转为 ,适用于绝大多数现代 Web 应用。
指定编码 urlencode(params, encoding='gbk') 当目标服务器要求使用 gbk 等旧编码时使用。慎用,优先用 utf-8
处理列表值 urlencode({'key': ['a', 'b']}) 自动处理为 key=a&key=b 的形式。
控制空格编码 urlencode(params, quote_via=quote) 使用 quote 函数,将空格编码为 %20,而不是 。
反向操作 from urllib.parse import unquote 将编码后的字符串(如 %E5%BC%A0%E4%B8%89)解码回原始中文(如 张三)。

处理 URL 中的非 ASCII 字符时,编码是关键步骤,而 urlencode Python 中完成这项任务最标准、最便捷的工具。

分享:
扫描分享到社交APP
上一篇
下一篇