【问题标题】:URL encoding/decoding with Python使用 Python 进行 URL 编码/解码
【发布时间】:2011-04-03 13:12:30
【问题描述】:

我正在尝试在 Python 中对参数进行编码、存储和解码,并在此过程中迷路了。这是我的步骤:

1) 我使用 google 工具包的 gtm_stringByEscapingForURLArgument 正确转换 NSString 以传递到 HTTP 参数。

2) 在我的服务器 (python) 上,我将这些字符串参数存储为 u'1234567890-/:;()$&@".,?!\'[]{}#%^*+=_\\|~<>\u20ac\xa3\xa5\u2022.,?!\'' 之类的东西(请注意,这些是 iPhone 键盘上“123”视图和“#+=”视图中的标准键, \u\x 字符中有一些货币前缀,如英镑、日元等)

3) 我在该存储值上调用urllib.quote(myString,''),大概是为了将它们转义以传输到客户端,以便客户端可以不百分比地转义它们。

结果是当我尝试记录 % 转义的结果时出现异常。是否有一些我忽略的关键步骤需要应用于 \u 和 \x 格式的存储值,以便正确转换它以通过 http 发送?

更新:标记为以下答案的建议对我有用。不过,我正在提供一些更新来解决下面的 cmets 问题。

我收到的异常引用了\u20ac 的问题。我不知道这是否是一个问题,而不是它是字符串中的第一个 unicode 字符。

\u20ac char 是“欧元”符号的 unicode。我基本上发现我会遇到问题,除非我使用 urllib2 quote 方法。

【问题讨论】:

  • 如果可能,请提供异常详细信息和跟踪。
  • 您的字符串似乎不是有效的 unicode 字符串。我试图简单地打印它,它给了我 \u20ac 字符的编码错误。

标签: python url-encoding


【解决方案1】:

您对 stdlib 不走运,urllib.quote 不适用于 unicode。如果您使用的是 django,则可以使用 django.utils.http.urlquote 与 unicode 一起正常工作

【讨论】:

    【解决方案2】:

    编码“原始” unicode 的 url 并没有真正的意义。你需要做的是首先.encode("utf8"),这样你就有一个已知的字节编码,然后是.quote()

    输出不是很漂亮,但应该是正确的 uri 编码。

    >>> s = u'1234567890-/:;()$&@".,?!\'[]{}#%^*+=_\|~<>\u20ac\xa3\xa5\u2022.,?!\''
    >>> urllib2.quote(s.encode("utf8"))
    '1234567890-/%3A%3B%28%29%24%26%40%22.%2C%3F%21%27%5B%5D%7B%7D%23%25%5E%2A%2B%3D_%5C%7C%7E%3C%3E%E2%82%AC%C2%A3%C2%A5%E2%80%A2.%2C%3F%21%27'
    

    请记住,如果您正在调试或其他任何事情,您将需要unquote()decode() 才能正确打印出来。

    >>> print urllib2.unquote(urllib2.quote(s.encode("utf8")))
    1234567890-/:;()$&@".,?!'[]{}#%^*+=_\|~<>€£¥•.,?!'
    >>> # oops, nasty  means we've got a utf8 byte stream being treated as an ascii stream
    >>> print urllib2.unquote(urllib2.quote(s.encode("utf8"))).decode("utf8")
    1234567890-/:;()$&@".,?!'[]{}#%^*+=_\|~<>€£¥•.,?!'
    

    事实上,这就是另一个答案中提到的django functions 的作用。

    函数 django.utils.http.urlquote() 和 django.utils.http.urlquote_plus() 是 Python 标准的版本 urllib.quote() 和 urllib.quote_plus() 使用非 ASCII 字符。 (数据先转换为UTF-8 编码。)

    如果您应用任何进一步的引号或编码以不破坏事物,请小心。

    【讨论】:

    • 你刚刚用 djang.utils.http.urlquote/unquote 拯救了我的一天!非常感谢。
    • 似乎在 Python3 中,quoteunquote 隐藏在 urllib.parse 中,而不是隐藏在 urilliburllib2 中。
    【解决方案3】:

    我想第二次 pycruft 的评论。 Web 协议已经发展了几十年,处理各种约定可能很麻烦。现在 URL 碰巧没有明确地为字符定义,而只是为字节(八位字节)定义。作为一个历史巧合,URL 是您只能假设但不能强制执行或安全地期望存在编码的地方之一。但是,这里有一个惯例是更喜欢 latin-1 和 utf-8 而不是其他编码。有一段时间,看起来“unicode percent escapes”会是未来,但他们从未流行起来。

    对于unicode 对象和八位字节strings 之间的区别(在Python str unicode 对象和bytes/@ 987654326@ Python 中的对象 >= 3.0)。不幸的是,根据我的经验,在 Python 2.x 中完全区分这两个概念有很多原因。

    更 OT,当你想接收第三方 HTTP 请求时,你不能绝对依赖以百分比转义、utf-8 编码的八位字节发送的 URL:可能偶尔会有%uxxxx 转义在那里,至少 firefox 2.x 曾在可能的情况下将 URL 编码为 latin-1,仅在必要时才编码为 utf-8。

    【讨论】:

      猜你喜欢
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      相关资源
      最近更新 更多