2010-04-28 30 views
50

Estoy tratando de iterar a través de un objeto JSON para importar datos, es decir, título y enlace. Parece que no puedo acceder al contenido pasado el :.Iterando a través de un objeto JSON

JSON:

[ 
    { 
     "title": "Baby (Feat. Ludacris) - Justin Bieber", 
     "description": "Baby (Feat. Ludacris) by Justin Bieber on Grooveshark", 
     "link": "http://listen.grooveshark.com/s/Baby+Feat+Ludacris+/2Bqvdq", 
     "pubDate": "Wed, 28 Apr 2010 02:37:53 -0400", 
     "pubTime": 1272436673, 
     "TinyLink": "http://tinysong.com/d3wI", 
     "SongID": "24447862", 
     "SongName": "Baby (Feat. Ludacris)", 
     "ArtistID": "1118876", 
     "ArtistName": "Justin Bieber", 
     "AlbumID": "4104002", 
     "AlbumName": "My World (Part II);\nhttp://tinysong.com/gQsw", 
     "LongLink": "11578982", 
     "GroovesharkLink": "11578982", 
     "Link": "http://tinysong.com/d3wI" 
    }, 
    { 
     "title": "Feel Good Inc - Gorillaz", 
     "description": "Feel Good Inc by Gorillaz on Grooveshark", 
     "link": "http://listen.grooveshark.com/s/Feel+Good+Inc/1UksmI", 
     "pubDate": "Wed, 28 Apr 2010 02:25:30 -0400", 
     "pubTime": 1272435930 
    } 
] 

He intentado utilizar un diccionario:

def getLastSong(user,limit): 
    base_url = 'http://gsuser.com/lastSong/' 
    user_url = base_url + str(user) + '/' + str(limit) + "/" 
    raw = urllib.urlopen(user_url) 
    json_raw= raw.readlines() 
    json_object = json.loads(json_raw[0]) 

    #filtering and making it look good. 
    gsongs = [] 
    print json_object 
    for song in json_object[0]: 
     print song 

Este código sólo imprime la información antes de :. (ignore la pista Justin Bieber :))

Respuesta

49

Su carga de los datos JSON es un poco frágil. En lugar de:

json_raw= raw.readlines() 
json_object = json.loads(json_raw[0]) 

realmente debería simplemente hacer:

json_object = json.load(raw) 

Usted no debe pensar en lo que se obtiene como un "objeto JSON". Lo que tienes es una lista. La lista contiene dos dicts. Los dicts contienen varios pares clave/valor, todas las cadenas. Cuando lo haces json_object[0], estás pidiendo el primer dict de la lista. Cuando itera sobre eso, con for song in json_object[0]:, itera sobre las teclas del dict. Porque eso es lo que obtienes cuando iteras sobre el dict. Si desea acceder al valor asociado con la clave en ese dict, debería usar, por ejemplo, json_object[0][song].

Nada de esto es específico de JSON. Son solo tipos básicos de Python, con sus operaciones básicas cubiertas en cualquier tutorial.

+0

i no lo entiendo. Traté de repetir lo que dice su refrán fuera de límites. Estoy bastante seguro de que es una pregunta sobre json – myusuf3

+7

No. Te estoy diciendo que iterar sobre el dict te da las llaves.Si desea iterar sobre otra cosa, tendrá que iterar sobre otra cosa. No dijiste lo que querías repetir. Un tutorial de Python sería un buen lugar para descubrir qué puede iterar y qué haría. –

+5

Desafortunadamente, es un poco difícil explicar todas las formas en que puede extraer datos de listas y diccionarios y cadenas en los 600 caracteres que puede poner en un comentario. Ya dije que deberías indexar el dict para obtener el valor asociado con una tecla. No estoy seguro de qué quieres repetir. El próximo paso es aprender sobre los tipos de Python incorporados. –

21

Después de deserializar el JSON, tiene un objeto python. Usa los métodos de objetos regulares.

En este caso, usted ha hecho una lista de diccionarios:

json_object[0].items() 

json_object[0]["title"] 

etc.

+0

¡gracias por la ayuda que funcionó! :) – myusuf3

8

Me gustaría resolver este problema de la misma familia

import json 
import urllib2 

def last_song(user, limit): 
    # Assembling strings with "foo" + str(bar) + "baz" + ... generally isn't 
    # as nice as using real string formatting. It can seem simpler at first, 
    # but leaves you less happy in the long run. 
    url = 'http://gsuser.com/lastSong/%s/%d/' % (user, limit) 

    # urllib.urlopen is deprecated in favour of urllib2.urlopen 
    site = urllib2.urlopen(url) 

    # The json module has a function load for loading from file-like objects, 
    # like the one you get from `urllib2.urlopen`. You don't need to turn 
    # your data into a string and use loads and you definitely don't need to 
    # use readlines or readline (there is seldom if ever reason to use a 
    # file-like object's readline(s) methods.) 
    songs = json.load(site) 

    # I don't know why "lastSong" stuff returns something like this, but 
    # your json thing was a JSON array of two JSON objects. This will 
    # deserialise as a list of two dicts, with each item representing 
    # each of those two songs. 
    # 
    # Since each of the songs is represented by a dict, it will iterate 
    # over its keys (like any other Python dict). 
    baby, feel_good = songs 

    # Rather than printing in a function, it's usually better to 
    # return the string then let the caller do whatever with it. 
    # You said you wanted to make the output pretty but you didn't 
    # mention *how*, so here's an example of a prettyish representation 
    # from the song information given. 
    return "%(SongName)s by %(ArtistName)s - listen at %(link)s" % baby 
45

Creo que probablemente significaba:

for song in json_object: 
    # now song is a dictionary 
    for attribute, value in song.iteritems(): 
     print attribute, value # example usage 
+0

para el atributo, valor en song.iteritems(): ¿qué significa la coma en esta línea? – zakdances

+0

Es lo mismo que 'for (attribute, value) en song.iteritems():', o '(var1, var2) = (1, 2)' o 'var1, var2 = 1, 2'. 'dict.iteritems()' produce 'pares' (clave, valor) '(tuplas). Buscar "desempaquetado de tupla de pitón". – tzot

22

Esta pregunta ha estado aquí por mucho tiempo, pero quería contribuir con la forma en que normalmente iterar a través de un objeto JSON. En el siguiente ejemplo, he mostrado una cadena codificada que contiene el JSON, pero la cadena JSON podría haber provenido de un servicio web o un archivo.

import json 

def main(): 

    # create a simple JSON array 
    jsonString = '{"key1":"value1","key2":"value2","key3":"value3"}' 

    # change the JSON string into a JSON object 
    jsonObject = json.loads(jsonString) 

    # print the keys and values 
    for key in jsonObject: 
     value = jsonObject[key] 
     print("The key and value are ({}) = ({})".format(key, value)) 

    pass 

if __name__ == '__main__': 
    main() 
+0

Los índices de cadena deben ser enteros, no str –

1

Para Python 3, debe decodificar los datos que obtiene del servidor web. Por ejemplo, yo decodificar los datos como UTF-8 y luego tratar con él:

# example of json data object group with two values of key id 
jsonstufftest = '{'group':{'id':'2','id':'3'}} 
# always set your headers 
headers = {'User-Agent': 'Moz & Woz'} 
# the url you are trying to load and get json from 
url = 'http://www.cooljson.com/cooljson.json' 
# in python 3 you can build the request using request.Request 
req = urllib.request.Request(url,None,headers) 
# try to connect or fail gracefully 
try: 
    response = urllib.request.urlopen(req) # new python 3 code -jc 
except: 
    exit('could not load page, check connection') 
# read the response and DECODE 
html=response.read().decode('utf8') # new python3 code 
# now convert the decoded string into real JSON 
loadedjson = json.loads(html) 
# print to make sure it worked 
print (loadedjson) # works like a charm 
# iterate through each key value 
for testdata in loadedjson['group']: 
    print (accesscount['id']) # should print 2 then 3 if using test json 

Si no decodificar obtendrá bytes vs errores de cadenas en Python 3.

Cuestiones relacionadas