urllib.quote()引发KeyError

发布于 2021-01-29 15:16:47

我使用了URI编码,urllib.quote("schönefeld")但是当字符串中存在一些非ASCII字符时,它会鸣叫

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

我的输入字符串是köln, brønshøj, schönefeld等。

当我尝试仅在Windows中打印语句时(使用python2.7,pyscripter IDE)。但是在linux中它引发了异常(我猜平台无关紧要)。

这是我正在尝试的:

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

探索问题的原因: 在中urllib.quote(),实际上是抛出异常return ''.join(map(quoter, s))

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)),对于s中的每个元素,都会调用quoter函数,最后列表将由’‘联接并返回。

对于非ascii char
è,等效键将%E8出现在_safe_map变量中。但是,当我调用quote(’è’)时,它会搜索密钥\xe8。这样密钥就不存在,并且抛出异常。

因此,我只是在try-except块内s = [el.upper().replace("\\X","%") for el in s]调用之前进行了修改''.join(map(quoter, s))。现在工作正常。

但是我很烦我所做的是正确的方法,否则还会产生其他问题吗?而且我确实有200多个linux实例,很难在所有实例中部署此修复程序。

关注者
0
被浏览
173
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您正在尝试引用Unicode数据,因此需要确定如何将其转换为URL安全字节。

    首先将字符串编码为字节。经常使用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'
    

    However, the encoding depends on what the server will accept. It’s best to
    stick to the encoding the original form was sent with.



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看