【问题标题】:How to navigate to URLs with \u in them?如何导航到其中包含 \u 的 URL?
【发布时间】:2018-09-12 05:28:25
【问题描述】:

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

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

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

【问题讨论】:

    标签: python python-3.x url character-encoding


    【解决方案1】:

    这是一种在 IRI 的路径和域部分中自动检测和编码非 ASCII 的方法:

    from urllib.request import quote  
    
    def iri_to_uri(iri):
        return ("".join([x if ord(x) < 128 else quote(x) for x in iri]))
    

    【讨论】:

      【解决方案2】:

      从技术上讲,这些不是有效的 URL,但它们是有效的 IRI (Internationalized Resource Identifiers),如 RFC 3987 中所定义。

      将 IRI 编码为 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 才提供“部分支持”,我不确定这意味着什么)。我很确定 Python2.7 中的 urllib2 不会,而 Python 3.6 中的 urllib.request 可能也不会。

      无论如何,如果您选择的 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)
      

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

      或者您可能想要一个更高级别的库,例如 hyperlink 来处理 RFC 3987 中的所有复杂问题(以及 RFC 3986,当前版本的 URI 规范 - requests 2.x 和Python 3.6 stdlib 句柄非常正确)。


      如果您必须手动处理 IRI,则很有可能您还必须处理 IDN Internationalized Domain Names 来代替 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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-09
        • 2021-08-07
        • 2012-06-04
        • 1970-01-01
        • 2018-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多