2011-02-06 11 views
64

Así que he pasado mucho tiempo en esto, y me parece que debería ser una solución simple. Intento utilizar la Autenticación de Facebook para registrar usuarios en mi sitio, y estoy tratando de hacerlo desde el lado del servidor. He llegado al punto donde consigo mi token de acceso, y cuando voy a:Cadena de diccionario en Python

https://graph.facebook.com/me?access_token=MY_ACCESS_TOKEN

consigo la información que estoy buscando como una cadena que es así:

{"id":"123456789","name":"John Doe","first_name":"John","last_name":"Doe","link":"http:\/\/www.facebook.com\/jdoe","gender":"male","email":"jdoe\u0040gmail.com","timezone":-7,"locale":"en_US","verified":true,"updated_time":"2011-01-12T02:43:35+0000"}

parece que yo debería ser capaz de utilizar dict(string) en esto, pero estoy recibiendo este error:

ValueError: dictionary update sequence element #0 has length 1; 2 is required

Así que he intentado usar la salmuera, pero esta tiene err o:

KeyError: '{'

He intentado utilizar django.serializers des-serializar pero tuvo resultados similares. ¿Alguna idea? Siento que la respuesta tiene que ser simple, y solo estoy siendo estúpido. ¡Gracias por cualquier ayuda!

+0

Si quiere evaluar la cadena como Python, puede necesitar cambiar su cadena: '" verificado ": true' falla a menos que se defina' true'. O puede usar '" verificado ": verdadero', o' "verificado": "verdadero" '. –

+2

@Matt: dudo que pueda cambiar el formato de salida de graph.facebook.com. –

+0

@Fred: Dado el título de la pregunta ("Cadena para diccionario en Python"), creo que podría cambiarla de Python antes de que llame a 'ast.literal_eval()'. Sin embargo, su respuesta (revisada) es correcta: un deserializador JSON es una mejor solución. –

Respuesta

132

¡Estos datos son JSON! Puede deserializarlo usando el json module incorporado si está en Python 2.6+; de lo contrario, puede usar el excelente simplejson module de terceros.

import json # or `import simplejson as json` if on Python < 2.6 

json_string = u'{ "id":"123456789", ... }' 
obj = json.loads(json_string) # obj now contains a dict of the data 
+2

¿Por qué pusiste 'u' delante de tu cadena JSON de ejemplo? –

+2

@John: Indica una [cadena Unicode] (http://docs.python.org/howto/unicode.html#the-unicode-type). Lo puse principalmente por costumbre, pero presumiblemente la API de Facebook puede devolver datos con caracteres que no sean ASCII; en ese caso, los datos estarían codificados (probablemente en UTF-8), y 'decode()' -ing arrojaría una cadena 'unicode', que es lo que usé en mi ejemplo. Además, [esta página] (http://www.json.org/fatfree.html) menciona que JSON siempre está en Unicode (busca el término, está a medio camino de bajada) – Cameron

+2

Indica un pequeño literal u Unicode en Python. El hábito no es una buena razón. "La codificación de caracteres del texto JSON siempre es Unicode". - [Uu] nicode NO es una codificación. Lo que json.loads() espera es lo que tiene "por cable", que generalmente es un objeto str codificado en ASCII. El único caso en el que alimentarías json.loads() un objeto Unicode intencionalmente es cuando una persona extraña lo había transmitido en UTF-16 y, como está documentado, debes decodificarlo tú mismo. –

13

Utilice ast.literal_eval para evaluar los literales de Python. Sin embargo, lo que tienes es JSON (nota "verdadera" por ejemplo), así que utiliza un deserializador JSON.

>>> import json 
>>> s = """{"id":"123456789","name":"John Doe","first_name":"John","last_name":"Doe","link":"http:\/\/www.facebook.com\/jdoe","gender":"male","email":"jdoe\u0040gmail.com","timezone":-7,"locale":"en_US","verified":true,"updated_time":"2011-01-12T02:43:35+0000"}""" 
>>> json.loads(s) 
{u'first_name': u'John', u'last_name': u'Doe', u'verified': True, u'name': u'John Doe', u'locale': u'en_US', u'gender': u'male', u'email': u'[email protected]', u'link': u'http://www.facebook.com/jdoe', u'timezone': -7, u'updated_time': u'2011-01-12T02:43:35+0000', u'id': u'123456789'}