Мне интересно, каков наилучший способ - или если есть простой способ со стандартной библиотекой - преобразовать URL с символами Unicode в имени домена и путь к эквивалентному URL ASCII, закодированному с доменом как IDNA и путь% -кодирован согласно RFC 3986.
Я получаю от пользователя URL в UTF-8. Так что, если они набрали http://➡.ws/♥
, я получу 'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'
на Python. И что я хочу, это 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'
Это правильно? Есть лучшие предложения? Есть ли простая функция стандартной библиотеки, чтобы сделать это?