urllib.quote () бросает KeyError

Чтобы кодировать URI, я использовал urllib.quote("schönefeld") но когда в строке есть несколько символов, отличных от ascii, это

 KeyError: u'\xe9' Code: return ''.join(map(quoter, s)) 

Мои входные строки: köln, brønshøj, schönefeld и т. Д.

  • BeatifulSoup4 get_text все еще имеет javascript
  • Декодирование с двойной кодировкой utf8 в Python
  • WebScraping с BeautifulSoup или LXML.HTML
  • subprocess.Popen с использованием относительных путей
  • Что я использую для реализации max-heap в Python?
  • Обработка сбоя подпроцесса в Windows
  • Когда я пробовал просто печатать заявления в окнах (с использованием python2.7, pyscripter IDE). Но в Linux это вызывает исключение (я думаю, платформа не имеет значения).

    Это то, что я пытаюсь:

     from commands import getstatusoutput queryParams = "schönefeld"; cmdString = "http://baseurl" + quote(queryParams) print getstatusoutput(cmdString) 

    Изучение причины проблемы: в urllib.quote() , фактически исключение – throwin at 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 будет вызываться функция-циферблат, и, наконец, список будет соединен с символом' 'и возвращен.

    Для _safe_map non-ascii эквивалентный ключ будет %E8 который представлен в переменной _safe_map . Но когда я \xe8 цитату ('è'), он ищет ключ \xe8 . Так что ключ не существует и исключение выбрано.

    Итак, я просто изменил s = [el.upper().replace("\\X","%") for el in s] перед вызовом ''.join(map(quoter, s)) в блоке try-except , Теперь он работает нормально.

    Но я раздражаю то, что я сделал, это правильный подход или он создаст любую другую проблему? А также у меня есть 200+ экземпляров Linux, которые очень сложно развернуть это исправление во всех случаях.

  • Как получить вызывающее выражение функции в Python?
  • Как настроить python ctypes 'c_wchar_p' и 'c_char_p' restype?
  • Выход в рекурсивной функции
  • Как заменить экземпляр в __init __ () на другой объект?
  • Эффективный способ найти длинную повторяющуюся строку для Python (From Programming Pearls)
  • Создание отдельных выходных файлов в потоке Hadoop
  • 3 Solutions collect form web for “urllib.quote () бросает KeyError”

    Вы пытаетесь указать данные 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, но в моем случае проблема заключалась в том, что карта (quoter, s) пыталась найти ключ u'\xe9' который не был в _safe_map . Однако \xe9 был, поэтому я решил проблему, заменив u'\xe9' на \xe9 в s .

    Более того, не должно ли выражение return быть внутри try/except ? Мне также пришлось изменить это, чтобы полностью решить проблему.

    Python - лучший язык программирования в мире.