urllib.quote()抛出KeyE

2024-05-16 23:47:48 发布

您现在位置:Python中文网/ 问答频道 /正文

为了对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字符è,等价键将是%E8,它出现在_safe_map变量中。但当我调用quote('è')时,它会搜索键\xe8。使密钥不存在并引发异常。

所以,我只是在调用try except块中的s = [el.upper().replace("\\X","%") for el in s]之前修改了''.join(map(quoter, s))。现在一切正常了。

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


Tags: 字符串mapreturnifasciiurllib字符safe
3条回答

您试图引用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'

但是,编码取决于服务器将接受什么。最好坚持原始表单的编码方式。

我的错误与@underline完全相同,但在我的例子中,问题是map(quoter,s)试图寻找不在_safe_map中的键u'\xe9'。但是\xe9是,所以我通过用s中的\xe9替换u'\xe9'来解决这个问题。

而且,return语句不应该在try/except中吗?我也不得不改变这个来彻底解决这个问题。

通过将字符串转换为unicode,我解决了这个问题。

以下是片段:

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

相关问题 更多 >