Python:Decoding' Idna'使用punycode时,字符无法正常工作

时间:2018-02-13 12:40:17

标签: python unicode

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

在我的应用程序中,我将字符指定为byte,然后解码idna类型。它适用于某些网址,而非所有网址

适用于此网址:

>>> url1= 'www.xn--alliancefranaise-npb.nu'
>>> r= url1.encode('utf-8')
>>> r.decode('idna')
'www.alliancefrançaise.nu'

不是这个

>>> url1= 'http://xn--espaol-zwa.come'
>>> r= url1.encode('utf-8')
>>> r.decode('idna')
'http://xn--espaol-zwa.come'

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

2 个答案:

答案 0 :(得分:1)

您需要specialized module,而不是依赖于encodings实施。

>>> import idna
>>> print (idna.decode('xn--espaol-zwa.come'))
español.come

idna模块的文档说:

  

这可以作为“encodings.idna”模块的合适替代品   随Python标准库一起提供,但只支持   旧的,已弃用的IDNA规范(RFC 3490)

答案 1 :(得分:1)

尽管被接受的答案本身是正确的。 Python内置的idna编解码器正在运行。我在3.5.2和3.7.0中进行了测试。真正的问题是该示例的标题错误。 idna编解码器严格用于DNS主机名而不是URL。

无效的原始示例:

>>> url1= 'http://xn--espaol-zwa.come'
>>> r= url1.encode('utf-8')
>>> r.decode('idna')
'http://xn--espaol-zwa.come'

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

>>> url1= 'xn--espaol-zwa.come'
>>> r= url1.encode('utf-8')
>>> r.decode('idna')
'español.come'

记住idna仅用于DNS主机名是很重要的,它只允许使用一组受限制的字符。不应将其应用于URL或嵌入了主机名的整个字符串。有一个内置的python punycode编解码器,它受到更严格的限制,只能正确处理删除了xn--前缀的punycode编码的字符串。我认为punycode是idna编解码器使用的基础编解码器,并且如果没有脚手架代码仅将主机名部分的前缀为xn--送入punycode编解码器,则punycode编解码器无法在更高级别使用,并且只能在xn--前缀不是xn--hostname-xyz.com的完整主机名,也不是xn--hostname-xyz只是主机名-xyz。