Как декодировать encodeURIComponent в GAE (python)?
у меня есть строка unicode, которая была закодирована на стороне клиента с помощью js encodeURIComponent.
Если я использую следующее в Python локально, я получаю ожидаемый результат:
>>> urllib.unquote("Foo%E2%84%A2%20Bar").decode("utf-8")
>>> u'Foou2122 Bar'
но когда я запускаю это в Google App Engine, я получаю:
Traceback (most recent call last):
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/_webapp25.py", line 703, in __call__
handler.post(*groups)
File "/base/data/home/apps/s~kaon-log/2.357769827131038147/main.py", line 143, in post
path_uni = urllib.unquote(h.path).decode('utf-8')
File "/base/python_runtime/python_dist/lib/python2.5/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 3-5: ordinal not in range(128)
Я все еще использую Python 2.5, если это имеет значение. Что я упускаю?
2 ответов
Я предполагаю, что h.path
является объектом unicode. Тогда urllib.unquote
вернет объект unicode. Когда decode
вызывается для объекта unicode сначала он преобразуется в str
используя кодировку по умолчанию (которая является ascii), и здесь вы получаете 'ascii' codec can't encode
исключения.
вот доказательство:
>>> urllib.unquote(u"Foo%E2%84%A2%20Bar").decode("utf-8")
...
UnicodeEncodeError: 'ascii' codec can't encode characters in position 3-5: ordinal not in range(128)
это должно работать:
urllib.unquote(h.path.encode('utf-8')).decode("utf-8")
существует поток stackoverflow, который объясняет, почему unicode не работает с urllib.unquote
: как отменить кавычки urlencoded строка unicode в python?
используйте этот класс вместо urllib2:
class URL(object):
'''encode/decode requested URL'''
def __init__(self):
self.charset = '/abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789.'
def encode(self,url):
return ''.join([c if c in self.charset else '%'+c.encode('hex').upper() for c in url])
def decode(self,url):
return re.compile('%([0-9a-fA-F]{2})',re.M).sub(lambda m: chr(int(m.group(1),16)), url)
пример:
import re
URL().decode(your URL)