Кодирование URL-параметров в Python: обход проблем urllib.quote

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы процентно закодировать параметры URL в Python, можно использовать urllib.parse.quote. Если вам требуется заменить пробелы символом +, воспользуйтесь urllib.parse.quote_plus.

  • Кодирование с помощью quote:

    Python
    Скопировать код
    from urllib.parse import quote
    print(quote('param с / & spaces')) 
    # Возвращает: 'param%20with%20%2F%20%26%20spaces'
  • Кодирование с помощью quote_plus:

    Python
    Скопировать код
    from urllib.parse import quote_plus
    print(quote_plus('param с / & spaces')) 
    # Возвращает: 'param+with+%2F+%26+spaces'
Кинга Идем в IT: пошаговый план для смены профессии

Работа с версиями Python и символами Unicode

Процентное кодирование наиболее удобно проводить в Python 3, поскольку в этой версии осуществляется полная поддержка Unicode. В Python 2 для работы с Unicode-символами их предварительно пришлось бы кодировать в UTF-8, в то время как Python 3 справляется с этой задачей без особого труда.

  • Python 2: Необходимы дополнительные шаги для кодирования:

    Python
    Скопировать код
    print(urllib.quote(u'üníćødé'.encode('utf-8')))  
    # Выводит: %C3%BCn%C3%AD%C4%87%C3%B3d%C3%A9
  • Python 3: Поддержка Unicode обеспечивается «из коробки»:

    Python
    Скопировать код
    from urllib.parse import quote
    print(quote('üníćødé'))  
    # Выводит: '%C3%BCn%C3%AD%C4%87%C3%B3d%C3%A9'

Используйте параметр safe в функции quote для указания символов, которые не должны подвергаться кодированию. По умолчанию он установлен на '/', что означает, что слеши не будут закодированы.

Python
Скопировать код
print(quote('param/with/slashes', safe=''))
# Выводит: 'param%2Fwith%2Fslashes'
Подробнее об этом расскажет наш спикер на видео
skypro youtube speaker

Как управлять 'безопасностью'

Параметр safe функции процентного кодирования по умолчанию установлен на '/', вот как с ним работать:

  • Символы [A-Za-z], [0-9] и '_.-~' кодировать незачем.
  • Если нужно, чтобы слеши были закодированы, установите safe=''.
  • Если требуется заменять пробелы на '+', выберите quote_plus. В противном случае функция quote закодирует пробелы как %20.

Воспользуйтесь urllib.parse.urlencode

Если вам нужно сформировать строку запроса URL с множеством параметров, подойдёт функция urllib.parse.urlencode. Она проста в использовании и позволяет легко форматировать запрос:

Python
Скопировать код
from urllib.parse import urlencode

params = {
  'name': 'John Doe',
  'job': 'Developer/Coder'
}
print(urlencode(params))  
# Выводит: 'name=John+Doe&job=Developer%2FCoder'

Эта функция преобразует словарь в формат, подходящий для части URL-запроса.

Визуализация

Можно представить процесс кодирования параметров URL как наклейку уникальных этикеток на символы:

Markdown
Скопировать код
Исходный символ: Пробел 🡒 " "       Вопросительный знак 🡒 "?"       Доллар 🡒 "$"
Закодированный:  Пробел 🡒 "%20"     Вопросительный знак 🡒 "%3F"      Доллар 🡒 "%24"

Схематичное представление процесса (URL-кодирование):

Markdown
Скопировать код
До кодирования📦: [А, Б, Пробел, В, Знак вопроса, Г, Доллар, Д]  
После кодирования📦: [А, Б, %20, В, %3F, Г, %24, Д]

Каждый специальный символ получает свою уникальную «этикетку», прежде чем отправиться в большой интернет.

Попробуйте альтернативные библиотеки

Хотя библиотека urllib в Python отлично подходит для работы с URL, есть и другие варианты:

  • Библиотека requests:

    Python
    Скопировать код
    from requests.utils import quote
  • Фреймворк Django:

    Python
    Скопировать код
    from django.utils.http import urlquote

Искусство декодирования URL

Иногда требуется обратное преобразование – декодирование URL. Для этой задачи подходит функция urllib.parse.unquote:

Python
Скопировать код
from urllib.parse import unquote
print(unquote('param%20with%20%2F%20%26%20spaces'))
# Выводит: 'param with / & spaces'

Изучите документацию на тему

При нужде в более подробном изучении темы обработки URL зайдите в документацию Python 3 по модулю urllib.parse. Она предоставит пошаговый мануал для решения любых задач.

Полезные материалы

  1. urllib.parse — Разбор URL на составляющиеофициальная документация Python.
  2. RFC 3986 – Унифицированный идентификатор ресурса (URI): Общий синтаксисофициальная спецификация.
  3. Как процентно-кодировать параметры URL в Python? – Stack Overflowобсуждение с примерами кодирования URL.
  4. Advanced Usage — Документация Requests — руководство по продвинутому использованию библиотеки Requests.
  5. HTML URL Encoding Referenceупрощенное объяснение и примеры кодирования URL.
  6. Процентное кодирование – Глоссарий MDN Web Docsобзор процесса кодирования.
  7. HTTP Made Really Easyподробное руководство по работе с HTTP.