2014-09-01 15 views
11

Próbuję wykonać proste parsowanie JSON przy użyciu modułu Python 3 wbudowanego w moduł JSON, a od przeczytania kilku innych pytań dotyczących SO i googling, wydaje się, że to jest całkiem proste. Jednak myślę, że otrzymuję ciąg zwracany zamiast oczekiwanego słownika.Python Json ładuje() zwracając ciąg zamiast słownika?

Po pierwsze, oto JSON, z którego próbuję uzyskać wartości. To tylko niektóre wyjście z Twittera 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}] 

I przypisany ten ciąg do zmiennej o nazwie json_string tak:

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

Wtedy, gdy próbuję uzyskać konkretny klucz z „Jason” słownika:

print(jason['hashtags']) 

dostaję błąd:

TypeError: string indices must be integers 

Chcę móc przekonwertować wyjście json do słownika, a następnie użyć wywołania jason[key_name], aby uzyskać wartości za pomocą określonych kluczy. Czy jest tu coś oczywistego, czego mi brakuje?

To jest moja pierwsza praca z Pythonem, po tym jak pochodzę z Javy. Uwielbiam ten język i myślę, że jest bardzo potężny. Tak więc wszelka pomoc w tym zakresie byłaby bardzo ceniona!

+2

1) Wklejone dane są strukturą danych w języku Python, a nie JSON. 2) Zewnętrzna struktura danych to * lista *, a nie słownik. –

+0

@LukasGraf Hmmm, interesujące. Więc jest to lista zawierająca słownik? Właśnie skomentowałem logikę json i właśnie wypróbowałem wyjście [0] ['hashtags'] bez szczęścia. "output" w tym przypadku jest strukturą danych Pythona zwróconą z połączenia. Wszelkie przemyślenia na temat tego, jak do tego podejść? –

+1

Jak inni zwrócili uwagę, twoje wejście JSON stanie się "listą" w Pythonie, a nie "dyktowaniem". Ponadto, fragment kodu, który podałeś, 'print (jason ['hashtags']), nie jest nawet poprawny w Pythonie ze względu na brak nawiasów zamykających. Proszę wysłać poprawny składnie przykład z jego wyjściami, abyśmy mogli być pewni jaki kod jest generowanie jakiego błędu –

Odpowiedz

4

Ok najpierw trzeba wydrukować obiektu, dzięki czemu można go przeczytać:

>>> 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}}] 

Od patrząc na to można zobaczyć ten wynik to list, który zawiera pojedynczy dict. Aby to uzyskać dostęp musisz:

>>> first_elem = output[0] 

Zobaczysz też, że kluczem w first_elemhashtags jest zawarty w drugim poziomie dict pod klucz 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': []} 

Teraz jesteś w stanie uzyskać dostęp hashtags :

>>> entities['hashtags'] 
[] 

Która akurat jest pustą listą.

Aby przekonwertować do formatu JSON, należy zwrócić uwagę na komentarz:

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

Myślę, że problemem jest to, że wykonane wyjście ciąg przed json.dumps to, co oznacza, że ​​json.loads zwróci ciąg, a nie obiekt JSON.

Odpowiedź @ Dan jest poprawna, to nie jest prawidłowy JSON. Jest to jednak poprawny droid Pythona i zakładam, że dostałeś go z Twittera używając Pythona, a następnie wydrukowałeś.

+2

Jego problemem było raczej to, że zakodował wynik, który był już Pythonem z powrotem do JSON, a następnie z powrotem do Pythona, a następnie uderzył w inny niezwiązany problem;) –

+0

Powrócę moją poprawkę do pytania - twoja odpowiedź ma dużo więcej sensu, jeśli pytanie pozostaje w swojej pierwotnej formie. –

+0

@Lukas ... cóż, jeśli chcesz uzyskać techniczne ...: P –

5

Po pierwsze, Twój przykład JSON nie jest poprawny JSON; API Twittera nie wyświetliłoby tego, ponieważ złamałoby każdego zgodnego konsumenta JSON.

  • jsonlint pokazuje pierwszy, oczywisty błąd składniowy: ciągi jedno-cytowane zamiast podwójnie cytowane.
  • Po drugie, trzeba None gdzie JSON wymaga null, False zamiast false i True zamiast true.

Twój domniemany przykład "JSON" został wstępnie zdekodowany na język Python :). Gdy używam fragment prawdziwej JSON, działa dokładnie tak, jak oczekiwano:

import json 

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

jason = json.loads(json_string) 

print(jason[0]["actual_json_key"]) 
Powiązane problemy