Найти - Пользователи
Полная версия: Обработать кириллическую строку из GET.
Начало » Python для новичков » Обработать кириллическую строку из GET.
1
monthy
Всем привет. Есть простейший скрипт wsgi, в одной части форма из двух инпутов и кнопки, которая передаёт данные GETом. Вторая часть эти данные берет, парсит url и присваивает двум переменным значения полученные из GET.
Проблема вроде бы типичная - не обрабатываются строки с кириллицей, например не работает .upper() Но ни обычные методы (в cli-скрипте помог .decode('utf-8') точно в такой же ситуации), ни тупой перебор всех возможных decode, encode и прочее - не помогает (а если быть точнее вываливается с ошибками UnicodeDecodeError или TypeError).

Возможно нужны какие-то подробности по окружению? Хост на ред хате, пайтон 2.7, локаль utf-8.
ZerG
Возможно кусочек кода и пример строки помог бы быстрее дать вам ответ.
http://python.su/forum/topic/724/
monthy
Первая часть, которая просто выводит форму
elif environ['PATH_INFO'] == '/' or environ['PATH_INFO'] == '/main':
        ctype = 'text/html'
        response_body = '''<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>Welcome to OpenShift</title>
</head>
<body>
    <form action="/justdoit" method="get">
        <input type="text" name="name">
        <input type="text" name="code">
        <input type="submit" value="Send">
    </form>
</body>
</html>'''

Вторая, которая парсит:
elif environ['PATH_INFO'] == '/justdoit':
        ctype = 'text/html'
        params = urlparse.parse_qs(environ.get('QUERY_STRING','utf-8'))
        name = str(params.get('name', [''])[0])
        code = str(params.get('code', [''])[0])
        print params
        print name
        print repr(name)
        print type(name)

Принты выводят вот это:
print params              {'code': ['123'], 'name': ['\\xd0\\xa2\\xd0\\xb5\\xd1\\x81\\xd1\\x82']}
print name \xd0\xa2\xd0\xb5\xd1\x81\xd1\x82
print repr(name) '\\xd0\\xa2\\xd0\\xb5\\xd1\\x81\\xd1\\x82'
print type(name) <type 'str'>

Если сделать unicode(name, ‘utf-8’), то выпадает с ошибкой: UnicodeEncodeError: ‘ascii’ codec can't encode characters in position 0-3: ordinal not in range(128)
Такая же ошибка выходит, при .decode('utf-8').
В данном случае в строке было слово Тест.




ayb
>>> print "\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82".decode('utf-8')
Тест

А вообще возьмите что-то легкое ( например боттл ) и вперед. Там об этом уже позаботились.
monthy
А вообще возьмите что-то легкое ( например боттл )
Это не вариант. У меня интерес не практический, а академический. Если в боттле, фласке или где-то еще это смогли реализовать, значит и я смогу. Инструмент не должен быть черным ящиком.
ayb
Инструмент не должен быть черным ящиком

Так у инструмента открытый исходный код ( да еще и с комментариями ).
monthy
Это, кстати, неплохой вариант, спасибо.

Частично нащупал решение:
Надо query string еще до парсинга обратить в юникод:
unicode(environ.get('QUERY_STRING'), 'utf-8')

Правда до конца разобраться не получается - почему-то текст выводится в ISO-8859-1, хотя все везде в utf - от системной локали, до charset в html. И encode('utf-8') выводимой строке тоже сделан.
monthy
Ок. У меня получилось, но я совсем ничего не понимаю.

Клюевым оказалось вот какое решение:
Сначала в юникод:
unicode(environ.get('QUERY_STRING'), 'utf-8')
Потом:
name = name.encode('latin-1').decode('utf-8')
И на вывод, опять:
name.encode('utf-8')

Может кто-то объяснить? Уже столько прочитано про encode|decode, но вот этот код, который заработал, совсем не вяжется с тем как я понимал эти методы. Например, я думал, что если строка “заэнкожена” одной кодировкой, то и декодить нужно из этой же кодировки.

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB