¿Python Json carga () la cadena de retorno en lugar del diccionario?

Estoy tratando de hacer un análisis JSON simple usando el módulo JSON incorporado en Python 3, y al leer un montón de otras preguntas sobre SO y buscar en Google, parece que se supone que esto es bastante sencillo. Sin embargo, creo que estoy obteniendo una cadena devuelta en lugar del diccionario esperado.

En primer lugar, aquí está el JSON del que estoy tratando de obtener valores. Es solo una salida de la API de Twitter

[{'in_reply_to_status_id_str': None, 'in_reply_to_screen_name': None, 'retweeted': False, 'in_reply_to_status_id': None, 'contributors': None, 'favorite_count': 0, 'in_reply_to_user_id': None, 'coordinates': None, 'source': 'Twitter Web Client', 'geo': None, 'retweet_count': 0, 'text': 'Tweeting a url \nhttp://t.co/QDVYv6bV90', 'created_at': 'Mon Sep 01 19:36:25 +0000 2014', 'entities': {'symbols': [], 'user_mentions': [], 'urls': [{'expanded_url': 'http://www.isthereanappthat.com', 'display_url': 'isthereanappthat.com', 'url': 'http://t.co/QDVYv6bV90', 'indices': [16, 38]}], 'hashtags': []}, 'id_str': '506526005943865344', 'in_reply_to_user_id_str': None, 'truncated': False, 'favorited': False, 'lang': 'en', 'possibly_sensitive': False, 'id': 506526005943865344, 'user': {'profile_text_color': '333333', 'time_zone': None, 'entities': {'description': {'urls': []}}, 'url': None, 'profile_background_image_url': 'http://sofes.miximages.com/python/bg.png', 'profile_background_image_url_https': 'http://sofes.miximages.com/python/bg.png', 'protected': False, 'default_profile_image': True, 'utc_offset': None, 'default_profile': True, 'screen_name': 'KickzWatch', 'follow_request_sent': False, 'following': False, 'profile_background_color': 'C0DEED', 'notifications': False, 'description': '', 'profile_sidebar_border_color': 'C0DEED', 'geo_enabled': False, 'verified': False, 'friends_count': 40, 'created_at': 'Mon Sep 01 16:29:18 +0000 2014', 'is_translator': False, 'profile_sidebar_fill_color': 'DDEEF6', 'statuses_count': 4, 'location': '', 'id_str': '2784389341', 'followers_count': 4, 'favourites_count': 0, 'contributors_enabled': False, 'is_translation_enabled': False, 'lang': 'en', 'profile_image_url': 'http://sofes.miximages.com/python/default_profile_6_normal.png', 'profile_image_url_https': 'http://sofes.miximages.com/python/default_profile_6_normal.png', 'id': 2784389341, 'profile_use_background_image': True, 'listed_count': 0, 'profile_background_tile': False, 'name': 'Maktub Destiny', 'profile_link_color': '0084B4'}, 'place': None}] 

Asigné esta cadena a una variable llamada json_string así:

 json_string = json.dumps(output) jason = json.loads(json_string) 

Luego, cuando bash obtener una clave específica del diccionario “jason”:

 print(jason['hashtags']) 

Estoy recibiendo un error:

 TypeError: string indices must be integers 

Quiero poder convertir la salida json a un diccionario, luego usar la llamada jason[key_name] para obtener valores usando las claves especificadas. ¿Hay algo obvio que me esté perdiendo aquí?

Esta es la primera vez que trabajo con Python, después de venir de Java. Me encanta el idioma y creo que es muy poderoso. Por lo tanto, cualquier ayuda en esto sería muy apreciada!

Ok, primero debes imprimir tu objeto para que puedas leerlo:

 >>> from pprint import pprint >>> output = [{'in_reply_to_status_id_str': None, 'in_reply_to_screen_name': None, 'retweeted': False, 'in_reply_to_status_id': None, 'contributors': None, 'favorite_count': 0, 'in_reply_to_user_id': None, 'coordinates': None, 'source': 'Twitter Web Client', 'geo': None, 'retweet_count': 0, 'text': 'Tweeting a url \nhttp://t.co/QDVYv6bV90', 'created_at': 'Mon Sep 01 19:36:25 +0000 2014', 'entities': {'symbols': [], 'user_mentions': [], 'urls': [{'expanded_url': 'http://www.isthereanappthat.com', 'display_url': 'isthereanappthat.com', 'url': 'http://t.co/QDVYv6bV90', 'indices': [16, 38]}], 'hashtags': []}, 'id_str': '506526005943865344', 'in_reply_to_user_id_str': None, 'truncated': False, 'favorited': False, 'lang': 'en', 'possibly_sensitive': False, 'id': 506526005943865344, 'user': {'profile_text_color': '333333', 'time_zone': None, 'entities': {'description': {'urls': []}}, 'url': None, 'profile_background_image_url': 'http://sofes.miximages.com/python/bg.png', 'profile_background_image_url_https': 'http://sofes.miximages.com/python/bg.png', 'protected': False, 'default_profile_image': True, 'utc_offset': None, 'default_profile': True, 'screen_name': 'KickzWatch', 'follow_request_sent': False, 'following': False, 'profile_background_color': 'C0DEED', 'notifications': False, 'description': '', 'profile_sidebar_border_color': 'C0DEED', 'geo_enabled': False, 'verified': False, 'friends_count': 40, 'created_at': 'Mon Sep 01 16:29:18 +0000 2014', 'is_translator': False, 'profile_sidebar_fill_color': 'DDEEF6', 'statuses_count': 4, 'location': '', 'id_str': '2784389341', 'followers_count': 4, 'favourites_count': 0, 'contributors_enabled': False, 'is_translation_enabled': False, 'lang': 'en', 'profile_image_url': 'http://sofes.miximages.com/python/default_profile_6_normal.png', 'profile_image_url_https': 'http://sofes.miximages.com/python/default_profile_6_normal.png', 'id': 2784389341, 'profile_use_background_image': True, 'listed_count': 0, 'profile_background_tile': False, 'name': 'Maktub Destiny', 'profile_link_color': '0084B4'}, 'place': None}] >>> pprint(output) [{'contributors': None, 'coordinates': None, 'created_at': 'Mon Sep 01 19:36:25 +0000 2014', 'entities': {'hashtags': [], 'symbols': [], 'urls': [{'display_url': 'isthereanappthat.com', 'expanded_url': 'http://www.isthereanappthat.com', 'indices': [16, 38], 'url': 'http://t.co/QDVYv6bV90'}], 'user_mentions': []}, 'favorite_count': 0, 'favorited': False, 'geo': None, 'id': 506526005943865344, 'id_str': '506526005943865344', 'in_reply_to_screen_name': None, 'in_reply_to_status_id': None, 'in_reply_to_status_id_str': None, 'in_reply_to_user_id': None, 'in_reply_to_user_id_str': None, 'lang': 'en', 'place': None, 'possibly_sensitive': False, 'retweet_count': 0, 'retweeted': False, 'source': 'Twitter Web Client', 'text': 'Tweeting a url \nhttp://t.co/QDVYv6bV90', 'truncated': False, 'user': {'contributors_enabled': False, 'created_at': 'Mon Sep 01 16:29:18 +0000 2014', 'default_profile': True, 'default_profile_image': True, 'description': '', 'entities': {'description': {'urls': []}}, 'favourites_count': 0, 'follow_request_sent': False, 'followers_count': 4, 'following': False, 'friends_count': 40, 'geo_enabled': False, 'id': 2784389341, 'id_str': '2784389341', 'is_translation_enabled': False, 'is_translator': False, 'lang': 'en', 'listed_count': 0, 'location': '', 'name': 'Maktub Destiny', 'notifications': False, 'profile_background_color': 'C0DEED', 'profile_background_image_url': 'http://sofes.miximages.com/python/bg.png', 'profile_background_image_url_https': 'http://sofes.miximages.com/python/bg.png', 'profile_background_tile': False, 'profile_image_url': 'http://sofes.miximages.com/python/default_profile_6_normal.png', 'profile_image_url_https': 'http://sofes.miximages.com/python/default_profile_6_normal.png', 'profile_link_color': '0084B4', 'profile_sidebar_border_color': 'C0DEED', 'profile_sidebar_fill_color': 'DDEEF6', 'profile_text_color': '333333', 'profile_use_background_image': True, 'protected': False, 'screen_name': 'KickzWatch', 'statuses_count': 4, 'time_zone': None, 'url': None, 'utc_offset': None, 'verified': False}}] 

Al observar esto, puede ver que la salida es una list que contiene un solo dict . Para acceder a esto necesitas:

 >>> first_elem = output[0] 

También verá que la clave de hashtags en first_elem está contenida en un dict segundo nivel bajo las entities clave:

 >>> entities = first_elem['entities'] >>> pprint(entities) {'hashtags': [], 'symbols': [], 'urls': [{'display_url': 'isthereanappthat.com', 'expanded_url': 'http://www.isthereanappthat.com', 'indices': [16, 38], 'url': 'http://t.co/QDVYv6bV90'}], 'user_mentions': []} 

Ahora puedes acceder a los hashtags :

 >>> entities['hashtags'] [] 

Lo que simplemente pasa a ser la lista vacía.

Para convertir a JSON, tenga en cuenta el comentario:

 >>> import json >>> # Make sure output is the list object not a string representing the object >>> json_string = json.dumps(output) >>> jason = json.loads(output) >>> jason[0]['entities']['hashtags'] [] 

Creo que su problema es que creó una cadena de salida antes de json.dumps , lo que significa que json.loads devolverá una cadena, no un objeto json.

Y la respuesta de @ Dan es correcta, esto no es JSON válido. Sin embargo, es un dict de python válido, y supongo que lo obtuvo de Twitter con python y luego lo imprimió.

En primer lugar, su ejemplo JSON no es JSON válido; la API de Twitter no generaría esto, porque rompería a todos los consumidores JSON conformes.

  • jsonlint muestra el primer error de syntax obvio: cadenas entre comillas simples en lugar de comillas dobles.
  • En segundo lugar, tiene None donde JSON requiere null , False lugar de false , y True , en lugar de true .

Su supuesto ejemplo “JSON” parece haber sido descodificado previamente en Python :). Cuando uso un fragmento de JSON real, funciona exactamente como se esperaba:

 import json json_string = r""" [{"actual_json_key":"actual_json_value"}] """ jason = json.loads(json_string) print(jason[0]["actual_json_key"])