2011-02-28 16 views
11

मेरे पास एक यूनिकोड स्ट्रिंग है जैसे '%C3%A7%C3%B6asd+fjkls%25asd' और मैं इस स्ट्रिंग को डीकोड करना चाहता हूं।
मैंने urllib.unquote_plus (str) का उपयोग किया लेकिन यह गलत काम करता है।पायथन यूआरएल यूनिकोड यूनिकोड

- expected : 'çöasd+fjkls%asd ' 
- result : 'çöasd fjkls%asd' 

डबल कोडित UTF-8 वर्णों (%C3%A7 and %C3%B6) गलत डीकोड कर रहे हैं।
मेरा पायथन संस्करण 2.7 एक लिनक्स डिस्ट्रो
के तहत अनुमानित परिणाम प्राप्त करने का सबसे अच्छा तरीका क्या है? अग्रिम

+3

कृपया अपने प्रयास किए गए सहायकों को एक पक्ष का समर्थन करें और 'आयात sys निष्पादित करने के परिणाम प्रकाशित करें; प्रिंट sys.stdout.encoding' –

+0

दरअसल, डिकोडिंग स्वयं शायद ठीक काम कर रहा है, लेकिन कंसोल डिस्प्ले के लिए रीकोडिंग में समस्या हो सकती है। – ncoghlan

उत्तर

27

आप 3 या 4 या 5 समस्या है ... लेकिन repr() और unicodedata.name() अपने मित्रों को कर रहे हैं; वे print fubar के परिणामों को संचारित करने वाले विभिन्न कंसोल एन्कोडिंग वाले लोगों द्वारा भ्रमित किए बिना भ्रम के बिना आपको जो कुछ मिला है, वह स्पष्ट रूप से आपको दिखाता है।

सारांश: या तो (ए) आप एक यूनिकोड ऑब्जेक्ट से शुरू करते हैं और उस पर अवांछित फ़ंक्शन लागू करते हैं या (बी) आप एक स्ट्र ऑब्जेक्ट से प्रारंभ करते हैं और आपका कंसोल एन्कोडिंग यूटीएफ -8 नहीं है।

यदि आप कहते हैं के रूप में आप एक यूनिकोड वस्तु के साथ शुरू:

>>> s0 = u'%C3%A7%C3%B6asd+fjkls%25asd' 
>>> print repr(s0) 
u'%C3%A7%C3%B6asd+fjkls%25asd' 

इस एक आकस्मिक बकवास है। यदि आप urllibX.unquote_YYYY() पर लागू करते हैं, तो आपको एक और बकवास यूनिकोड ऑब्जेक्ट (u'\xc3\xa7\xc3\xb6asd+fjkls%asd') मिलता है जो मुद्रित होने पर आपके दिखाए गए लक्षणों का कारण बनता है।आप एक str वस्तु तुरंत करने के लिए अपने मूल यूनिकोड वस्तु परिवर्तित करना चाहिए:

>>> s1 = s0.encode('ascii') 
>>> print repr(s1) 
'%C3%A7%C3%B6asd+fjkls%25asd' 

तो आप इसके गंदें शब्द बोलना चाहिए:

>>> import urllib2 
>>> s2 = urllib2.unquote(s1) 
>>> print repr(s2) 
'\xc3\xa7\xc3\xb6asd+fjkls%asd' 

कि के पहले 4 बाइट को देखते हुए, यह UTF-8 में एन्कोड किया। यदि आप print s2 करते हैं, तो यह ठीक लगेगा यदि आपका कंसोल यूटीएफ -8 की अपेक्षा कर रहा है, लेकिन यदि यह आईएसओ -885 9 -1 (उर्फ लैटिन 1) की अपेक्षा कर रहा है तो आपको अपना लक्षण कचरा दिखाई देगा (पहला चार ए-टिल्डे होगा)। चलो पार्क है कि एक पल के लिए सोचा और यह एक यूनिकोड वस्तु में बदलने का:

>>> s3 = s2.decode('utf8') 
>>> print repr(s3) 
u'\xe7\xf6asd+fjkls%asd' 

और देखने के लिए क्या हम वास्तव में मिल गया है यह निरीक्षण:

>>> import unicodedata 
>>> for c in s3[:6]: 
...  print repr(c), unicodedata.name(c) 
... 
u'\xe7' LATIN SMALL LETTER C WITH CEDILLA 
u'\xf6' LATIN SMALL LETTER O WITH DIAERESIS 
u'a' LATIN SMALL LETTER A 
u's' LATIN SMALL LETTER S 
u'd' LATIN SMALL LETTER D 
u'+' PLUS SIGN 

की तरह जो आपने कहा है कि आप की उम्मीद लग रहा है। अब हम इसे आपके कंसोल पर प्रदर्शित करने के सवाल पर आते हैं। नोट: जब आप "cp850" देखते हैं तो बाहर निकलना न करें; मैं यह पोर्टेबल कर रहा हूं और विंडोज़ पर कमांड प्रॉम्प्ट में ऐसा करने के लिए बस ऐसा करता हूं।

>>> import sys 
>>> sys.stdout.encoding 
'cp850' 
>>> print s3 
çöasd+fjkls%asd 

नोट: यूनिकोड ऑब्जेक्ट को sys.stdout.encoding का उपयोग करके स्पष्ट रूप से एन्कोड किया गया था। सौभाग्य से s3 में सभी यूनिकोड वर्ण उस एन्कोडिंग (और सीपी 1252 और लैटिन 1) में प्रतिनिधित्व योग्य हैं।

+0

मुझे ओपी के समान समस्या नहीं थी, लेकिन एन्कोडिंग और डिकोडिंग की आपकी स्पष्ट यात्रा ने मुझे तुरंत काम करने में मदद की जो मैं काफी दस्तावेज पढ़ने से नहीं कर पा रहा हूं। धन्यवाद। – KobeJohn

0

में

धन्यवाद urllib2 एक बार फिर प्रयास करें:

print urllib2.unquote('%C3%A7%C3%B6asd+fjkls%25asd') 
+0

आपके त्वरित उत्तर के लिए धन्यवाद मैंने पहले से ही कोशिश की है और यह मुझे एक ही परिणाम देता है। क्या आपके पास कोई अन्य सुझाव है? – user637287

0

'% C3% ए 7% C3% B6asd + fjkls% 25asd' - यह एक यूनिकोड स्ट्रिंग नहीं है।

यह एक यूआरएल-एन्कोडेड स्ट्रिंग है। इसके बजाय urllib2.unquote() का प्रयोग करें।

+0

यह परिणाम है:'> आयात urllib2 >>> urllib2.unquote प्रिंट करें ('% C3% A7% C3% B6asd + fjkls% 25asd') çöasd + fjkls% asd' मेरा पायथन संस्करण संस्करण अंतर के कारण 2.7 समस्या हो सकती है? – user637287

0

आप unquote_plus विधि का उपयोग कर रहे हैं जो space खाते में ले रहा है और + पर परिवर्तित कर रहा है। बस unquote विधि का उपयोग करें और आपको ठीक होना चाहिए।

>>> import urllib 
>>> print urllib.unquote('%C3%A7%C3%B6asd+fjkls%25asd') 
çöasd+fjkls%asd 
>>> print urllib.unquote_plus('%C3%A7%C3%B6asd+fjkls%25asd') 
çöasd fjkls%asd 
+0

असल में, मुझे उम्मीद है कि दूसरा आउटपुट है लेकिन मैं वही काम कर रहा हूं और यहां मेरा परिणाम है; '>> urllib आयात करें >>> urllib.unquote प्रिंट करें ('% C3% A7% C3% B6asd + fjkls% 25asd') çöasd + fjkls% asd >>> urllib.unquote_plus प्रिंट करें (' % सी 3% ए 7% सी 3% बी 6asd + fjkls% 25asd ') çöasd fjkls% asd' – user637287

+0

आपकी स्ट्रिंग को एसीआईआई ('s.encode (' ascii ')') पर एन्कोड करना और फिर quote_plus का उपयोग करना। यह करना चाहिए। –

0

आप एक डबल समस्या है: अपने स्ट्रिंग यूनिकोड इनकोडिंग है और caracter urlencoded शामिल हैं। कुछ मैच का उपयोग करते हुए या तो unquote या unquote_plus आप एक बाइट स्ट्रिंग दे देंगे

>>> s = '%C3%A7%C3%B6asd+fjkls%25asd' # ascii string 
>>> print urllib2.unquote(s) # works as expected 
çöasd+fjkls%asd 
>>> s = u'%C3%A7%C3%B6asd+fjkls%25asd' # unicode string 
>>> print urllib2.unquote(s) # decode stuff that it shouldn't 
çöasd+fjkls%asd 
>>> print urllib2.unquote(s.encode('ascii')) # encode the unicode string to ascii: works! 
çöasd+fjkls%asd 
+0

मुझे सच में लगता है कि मेरे पायथन संस्करण में कुछ गड़बड़ है क्योंकि मैंने आपका कोड कॉपी किया है लेकिन परिणाम फिर से 'çöasd + fjkls% asd' था। भले ही मैंने पहले से ही विकल्पों की जांच की है, क्या आप किसी भी अन्य मॉड्यूल को जानते हैं जिसका उपयोग मैं urllib – user637287

+0

के बजाय कर सकता हूं समस्या समस्या पाइथन होने की संभावना नहीं है। लेकिन ईमानदार होने के लिए, मैं बाहर या तर्कसंगत स्पष्टीकरण चला रहा हूं :-) क्या आपने वूडू की कोशिश की? क्या आपने इसे पाइथन शेल में सीधे कोशिश की है? यदि नहीं, तो आप अपनी फ़ाइल के एन्कोडिंग को इसके शीर्ष पर परिभाषित करना चाहेंगे। आपका ओएस क्या है? मैं खिड़कियों का अनुमान लगा रहा हूं क्योंकि बहुत सारे एन्कोडिंग मुद्दे हैं। –

+0

वूडू? थोड़ा पुराना; एक tambourine (http://www.elcomsoft.com/tambourine.html?r1=pr&r2=april1) या (बहुत बेहतर) 'repr()' अंतर्निर्मित फ़ंक्शन का प्रयास करें। 'Urllib.unquote_plus (u'äö'.encode ('ascii') के लिए –

9

: आप ascci करने के लिए अपने स्ट्रिंग को सामान्य यकीन है कि यह गलत तरीके से व्याख्या नहीं की जा होगा हो सकता है।

>>> print(urllib.unquote_plus('%C3%A7%C3%B6asd+fjkls%25asd')) 
çöasd fjkls%asd 
>>> 

ध्यान रखें कि आपके इनपुट स्ट्रिंग एक बाइट स्ट्रिंग होनी चाहिए:

>>> print(urllib.unquote_plus('%C3%A7%C3%B6asd+fjkls%25asd').decode('utf8')) 
çöasd fjkls%asd 
>>> 

के साथ तुलना में: आप एक यूनिकोड स्ट्रिंग चाहते हैं तो आप यूनिकोड को बाइट स्ट्रिंग डिकोड करने के लिए है, तो आप के लिए यूनिकोड पारित unquote/unquote_plus तो आपको थोड़ी सी गड़बड़ी मिल जाएगी। यदि यह मामला है तो यह पहले सांकेतिक शब्दों में बदलना:

>>> print(urllib.unquote_plus(u'%C3%A7%C3%B6asd+fjkls%25asd'.encode('ascii')).decode('utf8')) 
çöasd fjkls%asd 
+0

+1)। डीकोड ('utf8') 'मुझे Django 1.7 में एक [फ़ाइल अपलोड नाम] डीकोड करने के लिए इसकी आवश्यकता है (https: // docs .djangoproject.com/en/1.7/रेफरी/फ़ाइलें/अपलोड /)। – Larpon

+0

बहुत उपयोगी, धन्यवाद। –

संबंधित मुद्दे