Как параметры URL с процентным кодом в Python?
Вопрос
Если я сделаю
url = "http://example.com?p=" + urllib.quote(query)
- Это не кодирует
/
к%2F
(прерывает нормализацию OAuth) - Он не обрабатывает Unicode (он бросает исключение)
Есть ли лучшая библиотека?
Решение
От док:
urllib.quote(string[, safe])
Замените специальные символы в строке, используя Escape %XX. Буквы, цифры и символы '_.-' никогда не цитируются. По умолчанию эта функция предназначена для цитирования раздела пути URL. Необязательный безопасный параметр указывает дополнительные символы, которые не следует цитировать - его значение по умолчанию - '/'
Это означает, что проход '' для Safe решит вашу первую проблему:
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
Что касается второго выпуска, есть отчет об ошибке об этом здесь. Анкет Очевидно, это было зафиксировано в Python 3. Вы можете сделать это, кодируя как UTF8, как это:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
Кстати взглянуть на Urlencode
Примечание что urllib.quote
переехал в urllib.parse.quote
в Python3
Другие советы
В Python 3, urllib.quote
был перенесен в urllib.parse.quote
И он обрабатывает Unicode по умолчанию.
>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
Мой ответ похож на ответ Паоло.
Я думаю модуль requests
гораздо лучше. Это основано на urllib3
Анкет Вы можете попробовать это:
>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
Если вы используете Django, вы можете использовать Urlquote:
>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'
Обратите внимание, что изменения в Python, так как этот ответ был опубликован, означают, что теперь это устаревшая обертка. Из исходного кода Django 2.1 для django.utils.http:
A legacy compatibility wrapper to Python's urllib.parse.quote() function.
(was used for unicode handling on Python 2)
Лучше использовать urlencode
здесь. Не большая разница для одного параметра, но IMHO делает код более ясным. (Выглядит сбивает с толку видеть функцию quote_plus
! Особенно те, которые приходят из других языков)
In [21]: query='lskdfj/sdfkjdf/ksdfj skfj'
In [22]: val=34
In [23]: from urllib.parse import urlencode
In [24]: encoded = urlencode(dict(p=query,val=val))
In [25]: print(f"http://example.com?{encoded}")
http://example.com?p=lskdfj%2Fsdfkjdf%2Fksdfj+skfj&val=34
Док
urlencode: https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode
QUOTE_PLUS: https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus