【发布时间】:2010-10-22 16:55:21
【问题描述】:
我想知道最好的方法是什么——或者如果标准库有一个简单的方法——将域名和路径中带有 Unicode 字符的 URL 转换为等效的 ASCII URL,用域编码为 IDNA 和根据 RFC 3986 编码的路径。
我从用户那里得到一个 UTF-8 格式的 URL。因此,如果他们输入了http://➡.ws/♥,我会在 Python 中得到'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'。我想要的是 ASCII 版本:'http://xn--hgi.ws/%E2%99%A5'。
我目前所做的是通过正则表达式将 URL 拆分为多个部分,然后手动对域进行 IDNA 编码,并使用不同的 urllib.quote() 调用分别对路径和查询字符串进行编码。
# url is UTF-8 here, eg: url = u'http://➡.ws/㉌'.encode('utf-8')
match = re.match(r'([a-z]{3,5})://(.+\.[a-z0-9]{1,6})'
r'(:\d{1,5})?(/.*?)(\?.*)?$', url, flags=re.I)
if not match:
raise BadURLException(url)
protocol, domain, port, path, query = match.groups()
try:
domain = unicode(domain, 'utf-8')
except UnicodeDecodeError:
return '' # bad UTF-8 chars in domain
domain = domain.encode('idna')
if port is None:
port = ''
path = urllib.quote(path)
if query is None:
query = ''
else:
query = urllib.quote(query, safe='=&?/')
url = protocol + '://' + domain + port + path + query
# url is ASCII here, eg: url = 'http://xn--hgi.ws/%E3%89%8C'
这是正确的吗?有更好的建议吗?是否有一个简单的标准库函数可以做到这一点?
【问题讨论】: