¿Cómo urlencode una cadena de consulta en Python?

Estoy tratando de codificar esta cadena antes de enviarla.

queryString = 'eventName=' + evt.fields["eventName"] + '&' + 'eventDescription=' + evt.fields["eventDescription"]; 

urlencode() pasar sus parámetros a urlencode() como un mapeo (dict), o una secuencia de 2-tuplas, como:

 >>> import urllib >>> f = { 'eventName' : 'myEvent', 'eventDescription' : 'cool event'} >>> urllib.urlencode(f) 'eventName=myEvent&eventDescription=cool+event' 

Python 3 o superior

Utilizar:

 >>> urllib.parse.urlencode(f) eventName=myEvent&eventDescription=cool+event 

Tenga en cuenta que esto no hace la encoding url en el sentido comúnmente utilizado (mire la salida). Para eso use urllib.parse.quote_plus .

Python 2

Lo que estás buscando es urllib.quote_plus :

 >>> urllib.quote_plus('string_of_characters_like_these:$#@=?%^Q^$') 'string_of_characters_like_these%3A%24%23%40%3D%3F%25%5EQ%5E%24' 

Python 3

En Python 3, el paquete urllib se ha dividido en componentes más pequeños. Utilizará urllib.parse.quote_plus (tenga en cuenta el módulo secundario de parse )

 import urllib.parse urllib.parse.quote_plus(...) 

Contexto

  • Python (versión 2.7.2)

Problema

  • Desea generar una cadena de consulta urlencoded.
  • Tienes un diccionario u objeto que contiene los pares nombre-valor.
  • Desea poder controlar el orden de salida de los pares nombre-valor.

Solución

  • urllib.urlencode
  • urllib.quote_plus

Escollos

  • orden de salida arbitraria de pares nombre-valor
    • (Ver también: ¿Por qué Python está ordenando mi diccionario así? )
    • (Ver también: ¿Por qué el orden en los diccionarios y conjuntos es arbitrario? )
  • manejo de casos en los que NO le importa el orden de los pares nombre-valor
  • manejo de casos en los que SI se preocupa por el orden de los pares nombre-valor
  • manejo de casos en los que un solo nombre debe aparecer más de una vez en el conjunto de todos los pares nombre-valor

Ejemplo

La siguiente es una solución completa, que incluye cómo lidiar con algunos escollos.

 ### ******************** ## init python (version 2.7.2 ) import urllib ### ******************** ## first setup a dictionary of name-value pairs dict_name_value_pairs = { "bravo" : "True != False", "alpha" : "http://www.example.com", "charlie" : "hello world", "delta" : "1234567 !@#$%^&*", "echo" : "user@example.com", } ### ******************** ## setup an exact ordering for the name-value pairs ary_ordered_names = [] ary_ordered_names.append('alpha') ary_ordered_names.append('bravo') ary_ordered_names.append('charlie') ary_ordered_names.append('delta') ary_ordered_names.append('echo') ### ******************** ## show the output results if('NO we DO NOT care about the ordering of name-value pairs'): queryString = urllib.urlencode(dict_name_value_pairs) print queryString """ echo=user%40example.com&bravo=True+%21%3D+False&delta=1234567+%21%40%23%24%25%5E%26%2A&charlie=hello+world&alpha=http%3A%2F%2Fwww.example.com """ if('YES we DO care about the ordering of name-value pairs'): queryString = "&".join( [ item+'='+urllib.quote_plus(dict_name_value_pairs[item]) for item in ary_ordered_names ] ) print queryString """ alpha=http%3A%2F%2Fwww.example.com&bravo=True+%21%3D+False&charlie=hello+world&delta=1234567+%21%40%23%24%25%5E%26%2A&echo=user%40example.com """ 

¡Pruebe las solicitudes en lugar de urllib y no necesita molestarse con urlencode!

 import requests requests.get('http://youraddress.com', params=evt.fields) 

EDITAR:

Si necesita pares de nombre-valor ordenados o varios valores para un nombre, configure parámetros como:

 params=[('name1','value11'), ('name1','value12'), ('name2','value21'), ...] 

En lugar de usar un diccionario.

Python 3:

urllib.parse.quote_plus (string, safe = ”, encoding = None, errores = None)

Tenga en cuenta que urllib.urlencode no siempre hace el truco. El problema es que algunos servicios se preocupan por el orden de los argumentos, que se pierden al crear el diccionario. Para tales casos, urllib.quote_plus es mejor, como sugirió Ricky.

Prueba esto:

 urllib.pathname2url(stringToURLEncode) 

urlencode no funcionará porque solo funciona en diccionarios. quote_plus no produjo el resultado correcto.

En Python 3, esto funcionó conmigo.

 import urllib urllib.parse.quote(query) 

para futuras referencias (ej: para python3)

 >>> import urllib.request as req >>> query = 'eventName=theEvent&eventDescription=testDesc' >>> req.pathname2url(query) >>> 'eventName%3DtheEvent%26eventDescription%3DtestDesc' 

Si urllib.parse.urlencode () le está dando errores, pruebe el módulo urllib3.

La syntax es la siguiente:

 import urllib3 urllib3.request.urlencode({"user" : "john" }) 

Para su uso en scripts / progtwigs que necesitan ser compatibles con Python 2 y 3, el módulo seis proporciona funciones de comillas y urlencode:

 >>> from six.moves.urllib.parse import urlencode, quote >>> data = {'some': 'query', 'for': 'encoding'} >>> urlencode(data) 'some=query&for=encoding' >>> url = '/some/url/with spaces and %;!<>&' >>> quote(url) '/some/url/with%20spaces%20and%20%25%3B%21%3C%3E%26' 

Otra cosa que quizás no se haya mencionado ya es que urllib.urlencode() codificará los valores vacíos en el diccionario como la cadena None lugar de tener ese parámetro como ausente. No sé si esto es típicamente deseado o no, pero no se ajusta a mi caso de uso, por lo tanto, tengo que usar quote_plus .

urllib.urlencode ()