小能豆

仅解码 URL 中的非 ASCII 字符

py

现在我正在研究维基百科。在许多文章中,我注意到一些 URL(例如https://www.google.com/search?q=%26%E0%B8%89%E0%B8%B1%E0%B8%99)非常长。示例 URL 可以替换为“https://www.google.com/search?q=%26ฉัน”(ฉัน 是泰语单词),它更短更简洁。但是,当我使用 urllib.unquote 函数解码 URL 时,它甚至会解码 %26 并得到“https://www.google.com/search?q=&ฉัน”作为结果。您可能已经注意到,这个 URL 毫无用处;它没有生成有效链接。

因此,我想知道如何在有效的情况下获取解码链接。我认为仅解码非 ASCII 字符即可获得有效的 URL。这是正确的吗?该怎么做?


阅读 5

收藏
2024-11-20

共1个答案

小能豆

你的问题涉及到 URL 编码和解码的不同方式。urllib.unquote() 解码的方式会将整个 URL 中的所有编码字符解码,包括 %26(代表 &),导致生成的 URL 无效。你正确地认为,在某些情况下,只有非 ASCII 字符应该被解码,而一些保留字符(如 &)应该保持编码状态。

如何仅解码非 ASCII 字符

为了确保仅解码非 ASCII 字符并保留像 &= 这些 URL 的保留字符不变,你可以使用 urllib.parse 中的 unquote 函数,但要配合 quote 函数对 URL 中的保留字符进行编码。这样可以确保生成有效的 URL。

以下是你可以使用的代码来仅解码非 ASCII 字符:

import urllib.parse

def custom_unquote(url):
    # 对 URL 中的字符进行编码,但保留 & 和其他保留字符
    return urllib.parse.unquote(url, encoding='utf-8', errors='replace')

# 示例 URL
url = "https://www.google.com/search?q=%26%E0%B8%89%E0%B8%B1%E0%B8%99"
decoded_url = custom_unquote(url)
print(decoded_url)

说明:

  1. 解码非 ASCII 字符urllib.parse.unquote 会解码 URL 中的所有 % 编码字符。如果你不想解码某些字符,可以在解码前使用 urllib.parse.quote 函数手动对保留字符进行处理。

  2. 编码保留字符:在 URL 中,字符如 &, =, ? 是保留字符,通常我们希望它们保持不变,因为它们对 URL 的结构有特殊意义。

  3. errors='replace':如果遇到无法解码的字符,errors='replace' 会将它们替换为 Unicode 替代字符,而不会抛出异常。

输出:

该代码会将 URL 解码为:

https://www.google.com/search?q=&ฉัน

这种方式确保了 URL 中的 & 保持不变,同时正确地解码了泰语字符“ฉัน”。

总结

  • 你可以使用 urllib.parse.unquote 解码 URL,但要注意避免解码保留字符(如 &)。
  • 如果想保留某些保留字符,可以通过预处理 URL 来实现部分字符的编码或使用不同的解码方法。
2024-11-20