Подтвердить что ты не робот

Есть ли готовый jQuery-заменитель, который я могу использовать для urllib.quote и urllib.unquote в Python 2.6.5?

Python urllib.quote и urllib.unquote не корректно обрабатывают Unicode в Python 2.6.5. Вот что происходит:

In [5]: print urllib.unquote(urllib.quote(u'Cataño'))
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)

/home/kkinder/<ipython console> in <module>()

/usr/lib/python2.6/urllib.pyc in quote(s, safe)
   1222             safe_map[c] = (c in safe) and c or ('%%%02X' % i)
   1223         _safemaps[cachekey] = safe_map
-> 1224     res = map(safe_map.__getitem__, s)
   1225     return ''.join(res)
   1226 

KeyError: u'\xc3'

Кодирование значения для UTF8 также не работает:

In [6]: print urllib.unquote(urllib.quote(u'Cataño'.encode('utf8')))
Cataño

Он распознается как ошибка и существует исправление, но не для моей версии Python.

Что бы я хотел, это нечто похожее на urllib.quote/urllib.unquote, но корректно обрабатывает переменные Юникода, так что этот код будет работать:

decode_url(encode_url(u'Cataño')) == u'Cataño'

Любые рекомендации?

4b9b3361

Ответ 1

Python urllib.quote и urllib.unquote не обрабатывают Unicode правильно

urllib не обрабатывает Unicode вообще. URL-адреса не содержат символов, отличных от ASCII, по определению. Когда вы имеете дело с urllib, вы должны использовать только байтовые строки. Если вы хотите, чтобы они отображали символы Unicode, вам придется их кодировать и декодировать вручную.

IRI могут содержать символы не ASCII, кодируя их как последовательности UTF-8, но Python на данный момент не имеет irilib.

Кодирование значения для UTF8 также не работает:

In [6]: print urllib.unquote(urllib.quote(u'Cataño'.encode('utf8')))
Cataño

А, ну, теперь вы вводите Unicode в консоль и делаете print -Unicode на консоли. Обычно это ненадежно, особенно в Windows и в вашем случае с консолью IPython.

Введите длинный путь с помощью обратных косых последовательностей, и вы можете более легко увидеть, что бит urllib действительно работает:

>>> u'Cata\u00F1o'.encode('utf-8')
'Cata\xC3\xB1o'
>>> urllib.quote(_)
'Cata%C3%B1o'

>>> urllib.unquote(_)
'Cata\xC3\xB1o'
>>> _.decode('utf-8')
u'Cata\xF1o'

Ответ 2

"" Кодирование значения для UTF8 также не работает "" "... результатом вашего кода является объект str, который, по предположению, является входом, закодированным в UTF-8. Вам нужно его расшифровать или определить" не работает" - что вы ожидаете?

Примечание. Чтобы нам не нужно было угадывать кодировку вашего терминала и тип ваших данных, используйте print repr(whatever) вместо print whatever.

>>> # Python 2.6.6
... from urllib import quote, unquote
>>> s = u"Cata\xf1o"
>>> q = quote(s.encode('utf8'))
>>> u = unquote(q).decode('utf8')
>>> for x in (s, q, u):
...     print repr(x)
...
u'Cata\xf1o'
'Cata%C3%B1o'
u'Cata\xf1o'
>>>

Для сравнения:

>>> # Python 3.2
... from urllib.parse import quote, unquote
>>> s = "Cata\xf1o"
>>> q = quote(s)
>>> u = unquote(q)
>>> for x in (s, q, u):
...     print(ascii(x))
...
'Cata\xf1o'
'Cata%C3%B1o'
'Cata\xf1o'
>>>

Ответ 3

Я столкнулся с той же проблемой и использовал вспомогательную функцию для работы с функцией non-ascii и urllib.urlencode(которая включает в себя цитату и unquote):

def utf8_urlencode(params):
    import urllib as u
    # problem: u.urlencode(params.items()) is not unicode-safe. Must encode all params strings as utf8 first.
    # UTF-8 encodes all the keys and values in params dictionary
    for k,v in params.items():
        # TRY urllib.unquote_plus(artist.encode('utf-8')).decode('utf-8')
        if type(v) in (int, long, float):
            params[k] = v
        else:
            try:
                params[k.encode('utf-8')] = v.encode('utf-8')
            except Exception as e:
                logging.warning( '**ERROR utf8_urlencode ERROR** %s' % e )
    return u.urlencode(params.items()).decode('utf-8')

принят из Кодирование/декодирование Unicode URL с Python

Ответ 4

Итак, у меня была та же проблема: я хотел поместить параметры запроса в URL-адрес, но некоторые из них содержали странные символы (диакритики).

Работа с кодировкой давала грязный url и была хрупкой.

Мое решение заключалось в замене каждого символа акцента/странного юникода на его эквивалент ascii. Это легко благодаря unidecode: Каков наилучший способ удаления акцентов в строке юникода Python?

pip install unidecode

затем

from unidecode import unidecode
print unidecode(u"éèê") 
# prints eee

поэтому у меня есть чистый URL. Также работает для китайцев и т.д.