杰瑞科技汇

Python如何进行URL编码?

核心模块:urllib.parse

urllib.parse 模块包含以下几个核心函数,我们主要会用到:

Python如何进行URL编码?-图1
(图片来源网络,侵删)
  • urllib.parse.quote(string, safe='...'):对字符串进行 URL 编码。
  • urllib.parse.unquote(string):对 URL 编码的字符串进行解码。
  • urllib.parse.quote_plus(string, safe='...'):类似于 quote,但会将空格编码为 号。
  • urllib.parse.unquote_plus(string):解码 quote_plus 编码的字符串。
  • urllib.parse.urlparse(urlstring):解析 URL,将其拆分为各个组成部分(如协议、域名、路径等)。

URL 编码

URL 编码(也称为百分比编码)是一种将 URL 中不允许的字符转换为 加上两位十六进制数表示的机制,空格 ` 会被编码为%20`。

urllib.parse.quote() - 基本编码

这是最常用的编码函数,它会将除了字母、数字和 _.- 之外的所有字符都进行编码。

from urllib.parse import quote
# 需要编码的字符串,包含中文和特殊字符
original_string = "Python 编程 & 学习?path=/a b/"
# 进行编码
encoded_string = quote(original_string)
print(f"原始字符串: {original_string}")
print(f"编码后字符串: {encoded_string}")

输出:

原始字符串: Python 编程 & 学习?path=/a b/
编码后字符串: Python%20%E7%BC%96%E7%A8%8B%20%26%20%E5%AD%A6%E4%B9%A0%3Fpath%3D%2Fa%20b%2F

解释:

Python如何进行URL编码?-图2
(图片来源网络,侵删)
  • 空格 -> %20
  • -> %E7%BC%96
  • -> %E7%A8%8B
  • & -> %26
  • -> %3F
  • -> %2F
  • -> %3D

urllib.parse.quote_plus() - 编码空格为

这个函数在 quote 的基础上,会将空格 ` 编码为+号,这在表单数据提交(application/x-www-form-urlencoded` 格式)中非常常见。

from urllib.parse import quote_plus
original_string = "Python 编程 & 学习?path=/a b/"
# 进行编码,空格变为 +
encoded_string = quote_plus(original_string)
print(f"原始字符串: {original_string}")
print(f"quote_plus 编码后: {encoded_string}")

输出:

原始字符串: Python 编程 & 学习?path=/a b/
quote_plus 编码后: Python+%E7%BC%96%E7%A8%8B+%26+%E5%AD%A6%E4%B9%A0%3Fpath%3D%2Fa+b%2F

注意: 你可以看到,空格 ` 变成了+,而+本身也会被编码为%2B`。

safe 参数

我们希望某些特殊字符不被编码,可以使用 safe 参数,URL 的路径中通常包含 ,我们不希望它被编码。

Python如何进行URL编码?-图3
(图片来源网络,侵删)
from urllib.parse import quote
url_path = "/my/path/with spaces/and&symbols"
# 默认情况下,/ 会被编码
encoded_default = quote(url_path)
print(f"默认编码 (safe=''): {encoded_default}")
# 指定 / 不被编码
encoded_safe = quote(url_path, safe='/')
print(f"指定 safe='/': {encoded_safe}")

输出:

默认编码 (safe=''): %2Fmy%2Fpath%2Fwith%20spaces%2Fand%26symbols
指定 safe='/': /my/path/with%20spaces/and%26symbols

URL 解码

解码就是编码的逆过程,将 %xx 形式的字符转换回原始字符。

urllib.parse.unquote() - 基本解码

这是与 quote 对应的解码函数。

from urllib.parse import unquote
encoded_string = "Python%20%E7%BC%96%E7%A8%8B%20%26%20%E5%AD%A6%E4%B9%A0%3Fpath%3D%2Fa%20b%2F"
# 进行解码
decoded_string = unquote(encoded_string)
print(f"编码字符串: {encoded_string}")
print(f"解码后字符串: {decoded_string}")

输出:

编码字符串: Python%20%E7%BC%96%E7%A8%8B%20%26%20%E5%AD%A6%E4%B9%A0%3Fpath%3D%2Fa%20b%2F
解码后字符串: Python 编程 & 学习?path=/a b/

urllib.parse.unquote_plus() - 解码 为空格

这个函数与 quote_plus 对应,它会将 号解码回空格 ` `。

from urllib.parse import unquote_plus
encoded_string = "Python+%E7%BC%96%E7%A8%8B+%26+%E5%AD%A6%E4%B9%A0%3Fpath%3D%2Fa+b%2F"
# 进行解码,+ 变为空格
decoded_string = unquote_plus(encoded_string)
print(f"quote_plus 编码字符串: {encoded_string}")
print(f"unquote_plus 解码后: {decoded_string}")

输出:

quote_plus 编码字符串: Python+%E7%BC%96%E7%A8%8B+%26+%E5%AD%A6%E4%B9%A0%3Fpath%3D%2Fa+b%2F
unquote_plus 解码后: Python 编程 & 学习?path=/a b/

完整的 URL 编码和解码

在实际应用中,我们通常需要对 URL 的查询参数进行编码,而不是对整个 URL 进行编码,直接对整个 URL 编码可能会导致协议(http)、域名等部分也被错误编码。

正确的做法是:只对 URL 的查询参数部分进行编码

错误示范

from urllib.parse import quote
# 对整个 URL 进行编码,这是错误的
full_url = "https://www.example.com/search?q=Python 编程&lang=zh"
encoded_full_url = quote(full_url)
print(f"错误示范 - 编码整个URL: {encoded_full_url}")
# 这会导致 https, :, / 等字符被编码,URL失效

正确示范

使用 urllib.parse.urlparseurllib.parse.urlencode (通常与 quote_plus 结合使用) 是更规范的做法。

from urllib.parse import urlparse, urlencode, parse_qs, urlunparse
# 1. 定义要传递的参数
params = {
    'q': 'Python 编程',
    'lang': 'zh-CN',
    'sort': 'relevance & date'
}
# 2. 对参数进行编码 (使用 quote_plus 的逻辑)
# urlencode 会自动处理字典,并对键和值进行编码
encoded_query = urlencode(params)
print(f"编码后的查询字符串: {encoded_query}")
# 输出: q=Python+%E7%BC%96%E7%A8%8B&lang=zh-CN&sort=relevance+%26+date
# 3. 构建最终的、安全的 URL
base_url = "https://www.example.com/search"
final_url = f"{base_url}?{encoded_query}"
print(f"最终构建的URL: {final_url}")
# 4. 解析和提取参数
# 如果有一个包含查询参数的URL,可以这样解析它
parsed_url = urlparse(final_url)
print(f"\n解析后的URL对象: {parsed_url}")
print(f"查询参数部分: {parsed_url.query}")
# 5. 解码查询参数
# 使用 parse_qs 将查询字符串解析回字典
decoded_params = parse_qs(parsed_url.query)
print(f"解码后的参数字典: {decoded_params}")
# 注意:parse_qs 的值永远是列表,因为一个键可能有多个值

输出:

编码后的查询字符串: q=Python+%E7%BC%96%E7%A8%8B&lang=zh-CN&sort=relevance+%26+date
最终构建的URL: https://www.example.com/search?q=Python+%E7%BC%96%E7%A8%8B&lang=zh-CN&sort=relevance+%26+date
解析后的URL对象: ParseResult(scheme='https', netloc='www.example.com', path='/search', params='', query='q=Python+%E7%BC%96%E7%A8%8B&lang=zh-CN&sort=relevance+%26+date', fragment='')
查询参数部分: q=Python+%E7%BC%96%E7%A8%8B&lang=zh-CN&sort=relevance+%26+date
解码后的参数字典: {'q': ['Python 编程'], 'lang': ['zh-CN'], 'sort': ['relevance & date']}

总结与最佳实践

场景 推荐函数 说明
对 URL 的某个部分(如路径、查询值)进行编码 urllib.parse.quote()urllib.parse.quote_plus() quote_plus 更适合表单数据,会将空格转为 。
对整个 URL 进行编码(不推荐) - 通常会破坏 URL 结构,应只编码其组成部分。
解码一个被 quote 编码的字符串 urllib.parse.unquote() 标准解码,%20 变回空格。
解码一个被 quote_plus 编码的字符串 urllib.parse.unquote_plus() 变回空格。
构建带查询参数的 URL urllib.parse.urlencode() 最佳实践!它会自动处理字典,并对键和值进行正确的 quote_plus 编码。
解析 URL 中的查询参数 urllib.parse.urlparse() + urllib.parse.parse_qs() 先拆分 URL,再解析查询字符串。parse_qs 返回的值是列表。

核心要点:

  1. 不要直接对整个 URL 进行编码,这通常是错误的。
  2. 使用 urlencode 来构建带有查询参数的 URL,这是最安全、最规范的方法。
  3. quotequote_plus 的区别,主要在于空格的处理。
  4. 解码时使用与编码时对应的函数 (unquoteunquote_plus)。
分享:
扫描分享到社交APP
上一篇
下一篇