Как перейти к URL-адресам с u в них?
Я наткнулся на URL - адреса, в которых есть символы Unicode, такие как следующие (обратите внимание, что это не будет соответствовать допустимой странице-это просто пример).
http://my_site_name.com/u0442uab86u0454uab8eR-u0454u043d-u043c/23795908
Как я могу декодировать / кодировать такой URL с помощью Python, чтобы я мог успешно выполнить HTTP GET для получения данных с этой веб-страницы?
2 ответа:
Технически это недопустимые URL-адреса, но они являются допустимыми IRIs (Интернационализированные идентификаторы ресурсов ), как определено вRFC 3987 .
Способ кодирования ИРИ в URI таков:
- UTF-8 кодирует путь
- % - кодирование результирующего UTF-8
Например (взято из связанной статьи Википедии), это IRI:
https://en.wiktionary.org/wiki/Ῥόδος
... соответствует этому URI:
https://en.wiktionary.org/wiki/%E1%BF%AC%CF%8C%CE%B4%CE%BF%CF%82
Я верю
requests
обрабатывает их из коробки (хотя совсем недавно, и только "частичная поддержка" существует до 3.0, и я не уверен, что это означает). Я почти уверен, чтоurllib2
в Python2. 7 этого не делает, иurllib.request
в Python 3.6, вероятно, тоже.В любом случае, если выбранная вами HTTP-библиотека не обрабатывает IRIs, вы можете сделать это вручную:
def iri_to_uri(iri): p = urllib.parse.urlparse(iri) path = urllib.parse.quote_from_bytes(p.path.encode('utf-8')) p = [:2] + (path,) + p[3:] return urllib.parse.urlunparse(p2)
Существует также ряд сторонних библиотек для обработки IRIs, в основном отколотых от других проектов, таких как Twisted и Amara. Возможно, стоит поискать PyPI для одного из них. чем строить его самому.
Или вам может понадобиться библиотека более высокого уровня, например
hyperlink
это решает все сложные вопросы в RFC 3987 (и RFC 3986, текущей версии спецификации для URI-которая ниrequests
2.x ни Python 3.6 stdlib обрабатывать совершенно правильно).
Если вам приходится иметь дело с IRIs вручную, есть хороший шанс, что вам также придется иметь дело с IDNs Интернационализированными доменными именами вместо доменных имен ASCII, хотя технически это не связанные спецификации. Поэтому вы, вероятно, хотите сделать что-то вроде этого:
def iri_to_uri(iri): p = urllib.parse.urlparse(iri) netloc = p.netloc.encode('idna').decode('ascii') path = urllib.parse.quote_from_bytes(p.path.encode('utf-8')) p = [:1] + (netloc, path) + p[3:] return urllib.parse.urlunparse(p2)