Python:使用 punycode 无法正确解码“Idna”字符

Loo*_*ody 2 python unicode

我的应用程序从 Twitter 对象接收 URL。URL 采用 Punycode 格式,例如 \' http://xn--espaol-zwa.come \'

\n\n

在我的应用程序中,我将字符指定为字节,然后解码 idna 类型。它适用于某些 URL,但不适用于所有 URL

\n\n

它适用于此网址:

\n\n
>>> url1= \'www.xn--alliancefranaise-npb.nu\'\n>>> r= url1.encode(\'utf-8\')\n>>> r.decode(\'idna\')\n\'www.alliancefran\xc3\xa7aise.nu\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

不是这个

\n\n
>>> url1= \'http://xn--espaol-zwa.come\'\n>>> r= url1.encode(\'utf-8\')\n>>> r.decode(\'idna\')\n\'http://xn--espaol-zwa.come\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

我想要一个适用于任何 URL 的代码

\n

fre*_*gnu 5

尽管接受的答案本身是正确的。Python 内置 idna 编解码器正在工作。我在3.5.2和3.7.0中测试过。真正的问题是这个例子是错误的。idna 编解码器严格适用于 DNS 主机名而不是 URL。

\n\n

原始示例不起作用:

\n\n
>>> url1= 'http://xn--espaol-zwa.come'\n>>> r= url1.encode('utf-8')\n>>> r.decode('idna')\n'http://xn--espaol-zwa.come'\n
Run Code Online (Sandbox Code Playgroud)\n\n

删除 URL 前缀后不起作用的原始示例:

\n\n
>>> url1= 'xn--espaol-zwa.come'\n>>> r= url1.encode('utf-8')\n>>> r.decode('idna')\n'espa\xc3\xb1ol.come'\n
Run Code Online (Sandbox Code Playgroud)\n\n

重要的是要记住 idna 仅适用于 DNS 主机名,并且只允许使用有限的字符集。它不应该应用于 URL 或嵌入主机名的整个字符串。有一个内置的 Python punycode 编解码器,它的限制更加严格,只能正确处理删除了 xn-- 前缀的 punycode 编码字符串。我相信 punycode 是 idna 编解码器使用的底层编解码器,并且如果没有脚手架代码只提供带有 xn-- 前缀的主机名部分,并且只能解码后面的部分,则 punycode 编解码器无法在更高级别使用。 xn-- 前缀不是 xn--hostname-xyz.com 完整主机名,也不是 xn--hostname-xyz 只是主机名-xyz。

\n