Se eu fizer
url = "http://example.com?p=" + urllib.quote(query)
- Não codifica
/
para%2F
(quebra a normalização do OAuth) - Ele não lida com Unicode (gera uma exceção)
Existe uma biblioteca melhor?
Se eu fizer
url = "http://example.com?p=" + urllib.quote(query)
/
para %2F
(quebra a normalização do OAuth)Existe uma biblioteca melhor?
Respostas:
Dos documentos :
urllib.quote(string[, safe])
Substitua caracteres especiais na string usando o escape% xx. Letras, dígitos e os caracteres '_.-' nunca são citados. Por padrão, essa função se destina a citar a seção de caminho da URL. O parâmetro opcional safe especifica caracteres adicionais que não devem ser citados - seu valor padrão é '/'
Isso significa que passar '' para o cofre resolverá seu primeiro problema:
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
Sobre a segunda edição, há um relatório de bug sobre isso aqui . Aparentemente, ele foi corrigido no python 3. Você pode contornar isso codificando como utf8 assim:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
A propósito, dê uma olhada no urlencode
O mesmo, exceto substituir urllib.quote
por urllib.parse.quote
.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
É com isso que o urllib.quote está lidando.
urllib.quote
mudou-se para urlib.parse.quote
, desde Python3.
urllib.parse.quote
docs
No Python 3, urllib.quote
foi movido para urllib.parse.quote
e lida com unicode por padrão.
>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
quote
é bastante vago como um global. Pode ser mais agradável de usar algo como urlencode: from urllib.parse import quote as urlencode
.
urlencode
em urllib.parse
já que faz algo completamente diferente, então você seria melhor fora de escolher outro nome ou o risco de confundir seriamente futuros leitores do seu código.
Minha resposta é semelhante à resposta de Paolo.
Eu acho que o módulo requests
é muito melhor. É baseado em urllib3
. Você pode tentar isso:
>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
requests.utils.quote
é um invólucro compatibilidade fina para urllib.quote
para python 2 e urllib.parse.quote
para python 3
Se você estiver usando django, poderá usar urlquote:
>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'
Observe que as alterações no Python desde que esta resposta foi publicada significam que agora é um wrapper herdado. No código-fonte do Django 2.1 para django.utils.http:
A legacy compatibility wrapper to Python's urllib.parse.quote() function.
(was used for unicode handling on Python 2)
É melhor usar urlencode
aqui. Não há muita diferença para um único parâmetro, mas o IMHO torna o código mais claro. (Parece confuso ver uma função quote_plus
! Especialmente as que vêm de outros idiomas)
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