如何使用\ u导航到URL?

aBl*_*aze 5 python url character-encoding python-3.x

我遇到过其中包含\ u Unicode字符的URL,例如以下内容(请注意,这不会映射到有效页面 - 这只是一个示例).

http://my_site_name.com/\u0442\uab86\u0454\uab8eR-\u0454\u043d-\u043c/23795908

如何使用Python对这样的URL进行解码/编码,以便我可以成功地执行HTTP GET以从此网页检索数据?

aba*_*ert 5

从技术上讲,这些不是有效的 URL,但它们是有效的 IRI(国际化资源标识符),如RFC 3987 中所定义。

将 IRI 编码为 URI 的方式是:

  • UTF-8 编码路径
  • %-encode 得到的 UTF-8

例如(取自链接的维基百科文章),这个 IRI:

https://en.wiktionary.org/wiki/?????
Run Code Online (Sandbox Code Playgroud)

… 映射到这个 URI:

https://en.wiktionary.org/wiki/%E1%BF%AC%CF%8C%CE%B4%CE%BF%CF%82
Run Code Online (Sandbox Code Playgroud)

我相信可以requests开箱即用地处理这些(尽管最近才出现,并且只有“部分支持”直到 3.0,我不确定这意味着什么)。我很确定urllib2在 Python2.7 中没有,urllib.request在 Python 3.6 中可能也没有。

无论如何,如果您选择的 HTTP 库不处理 IRI,您可以手动完成:

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)
Run Code Online (Sandbox Code Playgroud)

还有一些第三方库可以处理 IRI,它们大多是从 Twisted 和 Amara 等其他项目中分离出来的。可能值得在 PyPI 中搜索一个而不是自己构建它。

或者,您可能想要一个像hyperlink这样的更高级别的库来处理 RFC 3987(以及RFC 3986,URI 规范的当前版本requests——2.x 和 Python 3.6 stdlib 都处理得不太正确)中的所有复杂问题。


如果您必须手动处理 IRI,则很有可能您还必须处理 IDN国际化域名来代替 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)
Run Code Online (Sandbox Code Playgroud)