Кодирование/декодирование URL с помощью Python
Я пытаюсь кодировать и хранить, и расшифровать аргументы в Python и заблудиться где-то по пути. Вот мои шаги:--9-->
1) я использую инструментарий google gtm_stringByEscapingForURLArgument
чтобы правильно преобразовать NSString для передачи в аргументы HTTP.
2) на моем сервере (python) я храню эти строковые аргументы как что-то вроде u'1234567890-/:;()$&@".,?!'[]{}#%^*+=_|~<>u20acxa3xa5u2022.,?!''
(обратите внимание, что это стандартные клавиши на клавиатуре iphone в представлении " 123 "и представлении"#+=",u
и x
chars там будучи некоторыми денежными префиксами, такими как фунт, иена и т. д.)
3) я называю urllib.quote(myString,'')
на этом сохраненном значении, предположительно до % - escape их для транспортировки клиенту, чтобы клиент мог unpercent избежать их.
в результате я получаю исключение, когда пытаюсь зарегистрировать результат % escaping. Есть ли какой-то важный шаг, который я пропускаю, который должен быть применен к сохраненному значению с форматом u и x, чтобы правильно преобразовать его для отправки протокол HTTP?
обновление: предложение, отмеченное как ответ ниже, сработало для меня. Тем не менее, я предоставляю некоторые обновления для рассмотрения приведенных ниже комментариев.
исключение, которое я получил, привело к проблеме с u20ac
. Я не знаю, была ли проблема именно в этом, а не в том, что это был первый символ юникода в строке.
это u20ac
char-это Юникод для символа "евро". Я в принципе нашел я проблемы с ним, если я не использовал urllib2 quote
метод.
3 ответов
url-кодировка" raw " unicode на самом деле не имеет смысла. Что вам нужно сделать, это .encode("utf8")
сначала у вас есть известная байтовая кодировка, а затем .quote()
что.
вывод не очень красивый, но он должен быть правильной кодировкой uri.
>>> s = u'1234567890-/:;()$&@".,?!\'[]{}#%^*+=_\|~<>\u20ac\xa3\xa5\u2022.,?!\''
>>> urllib2.quote(s.encode("utf8"))
'1234567890-/%3A%3B%28%29%24%26%40%22.%2C%3F%21%27%5B%5D%7B%7D%23%25%5E%2A%2B%3D_%5C%7C%7E%3C%3E%E2%82%AC%C2%A3%C2%A5%E2%80%A2.%2C%3F%21%27'
помните, что вам нужно будет как unquote()
и decode()
это, чтобы распечатать его правильно, если вы отлаживаете или что-то еще.
>>> print urllib2.unquote(urllib2.quote(s.encode("utf8")))
1234567890-/:;()$&@".,?!'[]{}#%^*+=_\|~<>€£¥•.,?!'
>>> # oops, nasty  means we've got a utf8 byte stream being treated as an ascii stream
>>> print urllib2.unquote(urllib2.quote(s.encode("utf8"))).decode("utf8")
1234567890-/:;()$&@".,?!'[]{}#%^*+=_\|~<>€£¥•.,?!'
это, на самом деле, то, что функции django упоминается в еще один ответ.
функции Джанго.а utils.http.urlquote() и Джанго.а utils.http.urlquote_plus() являются версии стандарта Python urllib.quote () и urllib.quote_plus() это работа с символами, отличными от ASCII. (Данные преобразуются в UTF-8 до кодировать.)
будьте осторожны, если вы применяете какие-либо дополнительные кавычки или кодировки, чтобы не калечить вещи.
Я хочу второе замечание pycruft по. веб-протоколы развивались на протяжении десятилетий, и работа с различными наборами конвенций может быть громоздкой. теперь URL-адреса явно не определены для символов, а только для байтов (октетов). как историческое совпадение, URL-адреса являются одним из мест, где вы можете только предполагать, но не применять или безопасно ожидать кодирования. тем не менее, существует соглашение, чтобы предпочесть latin-1 и utf-8 над другими кодировками здесь. какое-то время это выглядело как "процент unicode ускользает будет будущее, но они никогда не поймали на.
чрезвычайно важно быть педантично разборчивым в этой области о разнице между unicode
объекты и октет str
ings (в Python str объекты unicode и bytes
/bytearray
объекты в Python >= 3.0). к сожалению, по моему опыту, по ряду причин довольно сложно четко разделить две концепции в Python 2.икс.
еще больше OT, когда вы хотите получать сторонние HTTP-запросы, вы не можете полностью полагаться на URL-адреса, отправляемые в процентах-экранированных, utf-8-кодированных октетах: могут быть как случайные %uxxxx
побег там, и по крайней мере firefox 2.x используется для кодирования URL-адресов как latin-1, где это возможно, и как utf-8 только там, где это необходимо.
вам не повезло с stdlib, urllib.цитата не работает с Unicode. Если вы используете django, вы можете использовать django.а utils.http.urlquote, который правильно работает с unicode