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))
を変更しました。今では正常に動作します。
しかし、私がやったことは正しいアプローチであるか、それが他の問題を引き起こすでしょうか?また、Linuxの200以上のインスタンスがあり、すべてのインスタンスにこの修正プログラムを展開するのは非常に困難です。
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'
ただし、エンコーディングサーバーが受け入れるものによって異なります。元のフォームが送信されたエンコーディングに固執することをお勧めします。
文字列をユニコードに変換するだけで問題を解決しました。
ここにスニペットがあります:
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
@underscoreとまったく同じエラーがありましたが、私の場合、問題はmap(quoter、s)がu'\xe9'
にないキー_safe_map
を検索しようとしたことです。ただし、\xe9
はそうだったので、s
のu'\xe9'
を\xe9
に置き換えることで問題を解決しました。
さらに、return
ステートメントはtry/except
内にあるべきではありませんか?また、問題を完全に解決するためにこれを変更する必要がありました。