Якщо я це роблю
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.quotePython3.
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.quotepython 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