Como a porcentagem de parâmetros de URL de codificação no Python?
Pergunta
Se eu fizer
url = "http://example.com?p=" + urllib.quote(query)
- Não codifica
/
para%2F
(quebra a normalização do OAuth) - Não lida com o Unicode (joga uma exceção)
Existe uma biblioteca melhor?
Solução
De documentos:
urllib.quote(string[, safe])
Substitua caracteres especiais na string usando o %XX Escape. Cartas, dígitos e os personagens '_.-' nunca são citados. Por padrão, esta função destina -se a citar a seção de caminho do URL. O parâmetro seguro opcional especifica caracteres adicionais que não devem ser citados - Seu valor padrão é '/'
Isso significa que passar '' para Safe resolverá sua primeira edição:
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
Sobre a segunda edição, há um relatório de bug sobre isso aqui. Aparentemente, foi corrigido no Python 3. Você pode alterná -lo, codificando como UTF8 como este:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
A propósito, dê uma olhada urlencode
Observação este urllib.quote
mudou-se para urllib.parse.quote
em python3
Outras dicas
Em Python 3, urllib.quote
foi movido para urllib.parse.quote
E ele lida com o Unicode por padrão.
>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
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'
Se você estiver usando o Django, pode usar o UrlQuote:
>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'
Observe que as mudanças no Python, uma vez que essa resposta foi publicada significa que agora é um invólucro legado. Do 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 o parâmetro único, mas o IMHO torna o código mais claro. (Parece confuso ver uma função quote_plus
! especialmente aqueles 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
Documentos
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