Якщо я це роблю
url = "http://example.com?p=" + urllib.quote(query)
- Він не кодує
/
до%2F
(порушує нормалізацію OAuth) - Він не обробляє Unicode (він кидає виняток)
Чи є краща бібліотека?
Якщо я це роблю
url = "http://example.com?p=" + urllib.quote(query)
/
до %2F
(порушує нормалізацію OAuth)Чи є краща бібліотека?
Відповіді:
З документів :
urllib.quote(string[, safe])
Замініть спеціальні символи в рядку, використовуючи% xx escape. Букви, цифри та символи "_.-" ніколи не цитуються. За замовчуванням ця функція призначена для цитування розділу шляху URL-адреси. Необов’язковий безпечний параметр вказує додаткові символи, які не слід цитувати - його значення за замовчуванням - '/'
Це означає, що передача "" для безпечного вирішить вашу першу проблему:
>>> 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
.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
З чим має справу urllib.quote.
urllib.quote
переміщено до urlib.parse.quote
Python3.
urllib.parse.quote
docs
У 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/'
quote
досить неясна як глобальна. Може бути , краще використовувати що - щось на зразок UrlEncode: from urllib.parse import quote as urlencode
.
urlencode
в urllib.parse
уже, робить щось зовсім інше, тому вам краще вибрати інше ім’я або ризикнути серйозно заплутати майбутніх читачів вашого коду.
Моя відповідь схожа на відповідь Паоло.
Я думаю, що модуль requests
набагато краще. Це засновано на urllib3
. Ви можете спробувати це:
>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
requests.utils.quote
- це тонка обгортка сумісності urllib.quote
для python 2 та urllib.parse.quote
python 3
Якщо ви використовуєте 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