2010-08-25 169 views
45

我想在Python中编码,存储和解码参数,并在途中丢失某处。这里是我的步骤:使用Python进行URL编码/解码

1)我使用谷歌工具包的gtm_stringByEscapingForURLArgument正确地转换NSString传递到HTTP参数。我注意到这些字符串参数是u'1234567890-/:;()$&@".,?!\'[]{}#%^*+=_\\|~<>\u20ac\xa3\xa5\u2022.,?!\''(请注意,这些是“123”视图和“#+ =”视图中的iphone键盘上的标准键,这些键是在我的服务器(python) \u\x字符在那里是一些货币前缀像英镑,日元等)

3)我叫urllib.quote(myString,'')上存储的值,想必%-escape它们运输到客户端,以便客户端可以unpercent逃避它们。

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

更新:标记为下面答案的建议适用于我。不过,我提供了一些更新来解决下面的评论。

我收到的例外引用了\u20ac的问题。我不知道这是否与这个问题有关,而不是它是该字符串中的第一个unicode字符。

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

+1

请尽可能提供异常详情和跟踪。 – 2010-08-25 06:06:12

+0

看来你的字符串不是一个有效的Unicode字符串。我试图简单地打印它,它给了我\ u20ac字符的编码错误。 – 2010-08-25 07:05:39

回答

69

对“原始”unicode进行编码的网址实际上并不合理。你需要做的是.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之前 到编码。)

要小心,如果要应用任何进一步的报价或编码不裂伤的东西。

+2

你刚刚用djang.utils.http.urlquote/unquote拯救了我的一天!非常感谢。 – 2013-05-31 14:44:58

2

你对stdlib没有好运了,urllib.quote不能用于unicode。如果您使用的是django,则可以使用django.utils.http.urlquote,它可以与unicode一起正常工作

4

我想第二pycruft的评论。网络协议已经发展了数十年,处理各种各样的协议可能会很麻烦。现在URL恰好没有为字符明确定义,但仅适用于字节(八位字节)。作为历史巧合,URL是您只能假设的地方之一,但不能强制或安全地期望编码存在。然而,在这里有一个比其他编码更喜欢latin-1和utf-8的约定。有一段时间,它看起来像'unicode percent escapes'将是未来,但他们从来没有发现。

它是最重要的是在这方面的约unicode对象和八位字节str英格斯之间的差迂腐挑剔(在Python < 3.0;这是,容易混淆,str Unicode对象和在Python> = 3.0 bytes/bytearray对象) 。不幸的是,根据我的经验,很多原因很难在Python 2.x中完全分离这两个概念。

甚至更​​多OT,当您想要接收第三方HTTP请求时,您不能绝对依赖以百分比转义的,utf-8编码的八位字节发送的URL:这里可能偶尔会有%uxxxx转义,并且至少firefox 2.x用于在可能的情况下将URL编码为latin-1,并且只在必要时用作utf-8。