2013-02-27 26 views
33

फेंकता यूआरआई सांकेतिक शब्दों में बदलना करने के लिए मैं urllib.quote("schönefeld") इस्तेमाल किया, लेकिन जब कुछ गैर- ASCII वर्ण स्ट्रिंग में मौजूद है, यह thorwsurllib.quote(), KeyError

KeyError: u'\xe9' 
Code: return ''.join(map(quoter, s)) 

मेरे इनपुट तार कर रहे हैं köln, brønshøj, schönefeld आदि

जब मैंने विंडोज़ में केवल प्रिंटिंग कथन की कोशिश की (पायथन 2.7, पिस्क्रिप्टर आईडीई का उपयोग करना)। लेकिन लिनक्स में यह अपवाद उठाता है (मुझे लगता है कि मंच कोई फर्क नहीं पड़ता)।

यह मैं क्या कोशिश कर रहा हूँ है:

from commands import getstatusoutput 
queryParams = "schönefeld"; 
cmdString = "http://baseurl" + quote(queryParams) 
print getstatusoutput(cmdString) 

मुद्दा कारण तलाश:urllib.quote() में , वास्तव में अपवाद return ''.join(map(quoter, s)) पर throwin जा रहा है।

कोड urllib में है:

def quote(s, safe='/'): 
    if not s: 
     if s is None: 
      raise TypeError('None object cannot be quoted') 
     return s 
    cachekey = (safe, always_safe) 
    try: 
     (quoter, safe) = _safe_quoters[cachekey] 
    except KeyError: 
     safe_map = _safe_map.copy() 
     safe_map.update([(c, c) for c in safe]) 
     quoter = safe_map.__getitem__ 
     safe = always_safe + safe 
     _safe_quoters[cachekey] = (quoter, safe) 
     if not s.rstrip(safe): 
     return s 
     return ''.join(map(quoter, s)) 

अपवाद के लिए कारण, ''.join(map(quoter, s)) में है रों में प्रत्येक तत्व के लिए, quoter फ़ंक्शन कॉल किया जाएगा और अंत में सूची 'से' में शामिल हुए किया जाएगा और लौट आए।

गैर-असीसी चार è के लिए, समकक्ष कुंजी %E8 होगी जो _safe_map चर में प्रस्तुत होती है। लेकिन जब मैं उद्धरण ('è') कह रहा हूं, तो यह कुंजी \xe8 की खोज करता है। ताकि कुंजी मौजूद न हो और अपवाद फेंक दिया जाए।

तो, मैंने पर कॉल करने से पहले s = [el.upper().replace("\\X","%") for el in s] को संशोधित करने से पहले संशोधित किया। अब यह ठीक काम करता है।

लेकिन मुझे परेशान है कि मैंने जो किया है वह सही दृष्टिकोण है या यह कोई अन्य मुद्दा पैदा करेगा? और मेरे पास लिनक्स के 200+ उदाहरण भी हैं जो सभी मामलों में इस फिक्स को तैनात करना बहुत कठिन है।

+2

क्या यह पायथन 2 यूनिकोड मानों के साथ है? यह पहले से ही एन्कोडेड डेटा के लिए ठीक काम करता है। –

+1

आप 'urllib.quote ('sch \ xe9nefeld') के लिए त्रुटि प्राप्त नहीं करते हैं। आप * केवल * urllib.quote (u'sch \ xe9nefeld ') के लिए त्रुटि प्राप्त करें ('' '' यूनिकोड अक्षरशः नोट करें)। –

+1

@MartijnPieters तो 'cmdString = "http: // baseurl" + उद्धरण ("schönefeld")' यह 'cmdString = u" http: // baseurl "+ quote (u" schönefeld ") जैसा होना चाहिए? – Garfield

उत्तर

54

आप यूनिकोड डेटा उद्धृत करने का प्रयास कर रहे हैं, इसलिए आपको यह तय करने की आवश्यकता है कि इसे यूआरएल-सुरक्षित बाइट्स में कैसे चालू किया जाए।

पहले बाइट्स को स्ट्रिंग को एन्कोड करें। UTF-8 अक्सर प्रयोग किया जाता है:

>>> import urllib 
>>> urllib.quote(u'sch\xe9nefeld') 
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py:1268: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal 
    return ''.join(map(quoter, s)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 1268, in quote 
    return ''.join(map(quoter, s)) 
KeyError: u'\xe9' 
>>> urllib.quote(u'sch\xe9nefeld'.encode('utf8')) 
'sch%C3%A9nefeld' 

हालांकि, एन्कोडिंग क्या सर्वर स्वीकार करेंगे पर निर्भर करता है। मूल रूप से भेजा गया एन्कोडिंग एन्कोडिंग करना सबसे अच्छा है।

+0

utf-8 में आपके उत्तर का तात्पर्य है। [सभी प्रमुख ब्राउज़र यूआरआई -8 का उपयोग करते समय प्रतिशत-एन्कोडिंग से पहले utf-8] (http://www.w3.org/International/articles/idn-and-iri/#iriworks) का उपयोग करते हैं। [आईआरआई] (http://www.ietf.org/rfc/rfc3987) से [यूआरआई] (http://www.ietf.org/rfc/rfc3986) utf-8 का उपयोग करके परिवर्तित किया जाना चाहिए। विरासत सर्वर पर अन्य एन्कोडिंग का उपयोग किया जाता है। – jfs

+0

@ जेएफ। सेबेस्टियन: निश्चित रूप से, यूआरआई के पथ तत्व यूटीएफ -8 का उपयोग करते हैं। लेकिन इसके बजाय यह क्वेरी हिस्सा है। क्वेरी स्ट्रिंग में एन्कोडिंग के लिए कौन सा ब्राउज़र उपयोग करता है, कम परिभाषित किया गया है, और अतीत में, HTML पृष्ठ के एन्कोडिंग के आधार पर फ़ॉर्म बना हुआ है। –

2

स्ट्रिंग को यूनिकोड में परिवर्तित करके मैंने इस मुद्दे को हल किया।

यहाँ टुकड़ा है:

try: 
    unicode(mystring, "ascii") 
except UnicodeError: 
    mystring = unicode(mystring, "utf-8") 
else: 
    pass 

समाधान के विस्तृत विवरण http://effbot.org/pyfaq/what-does-unicodeerror-ascii-decoding-encoding-error-ordinal-not-in-range-128-mean.htm

0

में पाया जा सकता मैं @underscore के रूप में ठीक उसी त्रुटि थी लेकिन मेरे मामले में समस्या यह है कि नक्शा (quoter था, एस) ने u'\xe9' कुंजी देखने की कोशिश की जो _safe_map में नहीं था। हालांकि \xe9 था, इसलिए मैंने s में u'\xe9' को बदलकर इस मुद्दे को हल किया।

इसके अलावा, return कथन try/except के भीतर नहीं होना चाहिए? मुझे समस्या को पूरी तरह हल करने के लिए इसे भी बदलना पड़ा।

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