2014-09-01 2 views
11

Я пытаюсь сделать простой JSON-анализ, используя Python 3, встроенный в модуль JSON, и, читая кучу других вопросов о SO и googling, кажется, что это должно быть довольно просто. Однако, я думаю, что я получаю строку, возвращаемую вместо ожидаемого словаря.Python Json загружает() возвращающую строку вместо словаря?

Во-первых, вот JSON, с которого я пытаюсь получить значения. Это лишь некоторые выход из API Твиттера

[{'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': '<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>', '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://abs.twimg.com/images/themes/theme1/bg.png', 'profile_background_image_url_https': 'https://abs.twimg.com/images/themes/theme1/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://abs.twimg.com/sticky/default_profile_images/default_profile_6_normal.png', 'profile_image_url_https': 'https://abs.twimg.com/sticky/default_profile_images/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}] 

я присвоил эту строку в переменную с именем json_string как так:

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

Тогда, когда я пытаюсь получить определенный ключ из словаря «JASON»:

print(jason['hashtags']) 

Я получаю сообщение об ошибке:

TypeError: string indices must be integers 

Я хочу, чтобы иметь возможность конвертировать json-выход в словарь, а затем использовать вызов jason[key_name] для получения значений с использованием указанных ключей. Есть ли что-то очевидное, что я здесь отсутствует?

Это мое первое время, работая с Python после прихода с Java. Я очень люблю этот язык и считаю его очень мощным. Таким образом, любая помощь по этому поводу будет очень признательна!

+2

1) Эти данные, которые вы вставили, представляют собой структуру данных Python, а не JSON. 2) Внешняя структура данных - это * список *, а не словарь. –

+0

@ LukasGraf Хммм, интересно. Итак, это список, содержащий словарь? Я просто прокомментировал логику json и просто попробовал выход [0] ['hashtags'] без везения. «вывод» в этом случае является структурой данных Python, возвращенной из вызова. Любые мысли о том, как подойти к этому? –

+1

Как указывали другие, ваш вход JSON станет «списком» в Python, а не 'dict'. Кроме того, фрагмент кода, который вы указали, 'print (jason ['hashtags']', даже не является допустимым Python из-за отсутствия закрывающейся скобки. Пожалуйста, отправьте синтаксически правильный пример с его результатом, чтобы мы могли быть уверены, какой код что вызывает ошибку –

ответ

4

Ok сначала вы должны напечатать объект, так что вы можете прочитать:

>>> 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': '<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>', '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://abs.twimg.com/images/themes/theme1/bg.png', 'profile_background_image_url_https': 'https://abs.twimg.com/images/themes/theme1/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://abs.twimg.com/sticky/default_profile_images/default_profile_6_normal.png', 'profile_image_url_https': 'https://abs.twimg.com/sticky/default_profile_images/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': '<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>', 
    '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://abs.twimg.com/images/themes/theme1/bg.png', 
      'profile_background_image_url_https': 'https://abs.twimg.com/images/themes/theme1/bg.png', 
      'profile_background_tile': False, 
      'profile_image_url': 'http://abs.twimg.com/sticky/default_profile_images/default_profile_6_normal.png', 
      'profile_image_url_https': 'https://abs.twimg.com/sticky/default_profile_images/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}}] 

Глядя на это вы можете увидеть этот вывод является list, который содержит один dict. Чтобы получить доступ к этому вам нужно:

>>> first_elem = output[0] 

Вы также увидите, что hashtags ключ в first_elem содержится во втором уровне dict под ключ entities:

>>> 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': []} 

Теперь вы можете получить доступ к hashtags :

>>> entities['hashtags'] 
[] 

Это просто пустой список.

Для преобразования в формат JSON, обратите внимание, комментарий:

>>> 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'] 
[] 

Я думаю, ваша проблема в том, что вы сделали выход строку, прежде чем json.dumps это означает, что json.loads возвращает строку, а не объект JSON.

И ответ Дана правильный, это недействительно JSON. Это, однако, действительный python dict, и я предполагаю, что вы получили его из Twitter с помощью python, а затем распечатали его.

+2

Его проблема скорее заключалась в том, что он закодировал результат, который уже был Python, вернулся в JSON, а затем снова вернулся к Python, а затем ударил другую несвязанную проблему;) –

+0

Я верну свое редактирование на вопрос - ваш ответ будет иметь больше смысла, если вопрос останется в его первоначальной форме. –

+0

@ Луки ... ну, если ты хочешь получить техническую ...: P –

5

Во-первых, ваш пример JSON недействителен JSON; API Twitter не выдаст этого, потому что он сломает каждого соответствующего потребителя JSON.

  • jsonlint показывает первую очевидную синтаксическую ошибку: одиночные кавычки, а не двойные кавычки.
  • Во-вторых, у вас есть None где JSON требует null, False вместо false и True, вместо true.

Ваш предполагаемый пример «JSON», по-видимому, был предварительно декодирован в Python :). Когда я использую фрагмент реальной JSON, это работает точно так же, как и ожидалось:

import json 

json_string = r""" 
[{"actual_json_key":"actual_json_value"}] 
""" 

jason = json.loads(json_string) 

print(jason[0]["actual_json_key"]) 
Смежные вопросы