2011-11-28 8 views
9

Tengo un problema sobre urlencode en Python 2.7:¿Por qué no puedo usar urlencode para codificar datos de formato json?

>>> import urllib 
>>> import json 
>>> urllib.urlencode(json.dumps({'title':"hello world!",'anonymous':False,'needautocategory':True})) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/urllib.py", line 1280, in urlencode 
    raise TypeError 
TypeError: not a valid non-string sequence or mapping object 

Respuesta

13

urlencode puede codificar un dict, pero no una cadena. La salida de json.dumps es una cadena.

Dependiendo de qué salida que desee, o bien no codificar los dict en JSON:

>>> urllib.urlencode({'title':"hello world!",'anonymous':False,'needautocategory':True}) 
'needautocategory=True&anonymous=False&title=hello+world%EF%BC%81' 

o envolver todo el asunto en un diccionario:

>>> urllib.urlencode({'data': json.dumps({'title':"hello world!",'anonymous':False,'needautocategory':True})}) 
'data=%7B%22needautocategory%22%3A+true%2C+%22anonymous%22%3A+false%2C+%22title%22%3A+%22hello+world%5Cuff01%22%7D' 

o utilizar en lugar quote_plus() (urlencode utiliza quote_plus para las claves y los valores):

>>> urllib.quote_plus(json.dumps({'title':"hello world!",'anonymous':False,'needautocategory':True})) 
'%7B%22needautocategory%22%3A+true%2C+%22anonymous%22%3A+false%2C+%22title%22%3A+%22hello+world%5Cuff01%22%7D' 
+0

Tenga en cuenta que 'quote_plus()' transformará sus espacios en '+'. Cuando se trata de JSON es posible que desee mantenerlos como '% 20', use' quote() 'para ese – neric

2

json.dumps() devuelve una cadena.

urllib.urlencode() espera una consulta en el formato de un objeto de mapeo o tuplas. Tenga en cuenta que no espera una cadena.

Estás pasando el primero como el parámetro para el segundo, lo que provoca el error.

1

bibliotecas de importación

especificación
import request 
import json 

es un objeto de diccionario diccionario

spec = {...} 

convertido objeto de JSON

data = json.dumps(spec, ensure_ascii=False) 

y finalmente hacer la solicitud con especificación de parámetros en formato JSON

response = requests.get(
    'http://localhost:8080/...', 
    params={'spec': data} 
) 

analizar la respuesta ...

+0

No es una buena práctica pegar un código sin explicarlo. – miq

+0

lo siento, 'las prisas' o la velocidad –

Cuestiones relacionadas