为了对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 :(得分:59)
您正在尝试引用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'
但是,编码取决于服务器将接受的内容。最好坚持原始表格的编码。
答案 1 :(得分:2)
通过将字符串转换为unicode,我解决了这个问题。
这是片段:
try:
unicode(mystring, "ascii")
except UnicodeError:
mystring = unicode(mystring, "utf-8")
else:
pass
找到
答案 2 :(得分:1)
我和@underscore有完全相同的错误,但在我的情况下问题是地图(引用,s)试图寻找u'\xe9'
中没有的密钥_safe_map
。但是\xe9
是,所以我在u'\xe9'
中将\xe9
替换为s
来解决问题。
此外,return
声明不应该在try/except
范围内吗?我还必须改变它以完全解决问题。