2010-08-25 172 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。