简体   繁体   English

Python Json加载()返回字符串而不是字典?

[英]Python Json loads() returning string instead of dictionary?

I'm trying to do some simple JSON parsing using Python 3's built in JSON module, and from reading a bunch of other questions on SO and googling, it seems this is supposed to be pretty straightforward.我正在尝试使用 Python 3 的内置 JSON 模块进行一些简单的 JSON 解析,并且通过阅读有关 SO 和谷歌搜索的一堆其他问题,这似乎应该非常简单。 However, I think I'm getting a string returned instead of the expected dictionary.但是,我认为我得到的是返回的字符串而不是预期的字典。

Firstly, here is the JSON I am trying to get values from.首先,这是我试图从中获取值的 JSON。 It's just some output from Twitter's API这只是 Twitter 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 assigned this String to a variable named json_string like so:我将此字符串分配给一个名为 json_string 的变量,如下所示:

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

Then, when I try to get a specific key from the "jason" dictionary:然后,当我尝试从“jason”字典中获取特定键时:

print(jason['hashtags'])

I'm getting an error:我收到一个错误:

TypeError: string indices must be integers

I want to be able to convert the json output to a dictionary, then use jason[key_name] call to get values using specified keys.我希望能够将 json 输出转换为字典,然后使用jason[key_name]调用来使用指定的键获取值。 Is there something obvious that I'm missing here?我在这里有什么明显的遗漏吗?

This is my fist time working with Python, after coming from Java.这是我从 Java 毕业后第一次使用 Python。 I absolutely love the language and think it's very powerful.我非常喜欢这种语言,并认为它非常强大。 So, any help on this would be greatly appreciated!因此,非常感谢您对此的任何帮助!

Ok first you should print your object so that you can read it:好的,首先您应该打印您的对象,以便您可以阅读它:

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

From looking at this you can see that output is a list which contains a single dict .通过查看这个,您可以看到输出是一个包含单个dictlist To access this you need:要访问它,您需要:

>>> first_elem = output[0]

You will also see that the hashtags key in the first_elem is contained in a second level dict under the key entities :您还将看到first_elem hashtags包含在键entities下的第二级dict中:

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

Now you are able to access hashtags :现在您可以访问hashtags

>>> entities['hashtags']
[]

Which just happens to be the empty list.这恰好是空列表。

To convert to JSON, note the comment:要转换为 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']
[]

I think your problem is that you made output a string before you json.dumps it, meaning that json.loads will return a string, not a json object.我认为您的问题是您在json.dumps之前输出了一个字符串,这意味着json.loads将返回一个字符串,而不是一个 json 对象。

And @Dan's answer is correct, this is not valid JSON. @Dan 的回答是正确的,这不是有效的 JSON。 It is however a valid python dict, and I'm assuming that you got it from Twitter using python then printed it.然而,它是一个有效的 python 字典,我假设你使用 python 从 Twitter 获得它然后打印它。

First off, your JSON example is not valid JSON;首先,您的 JSON 示例不是有效的 JSON; the Twitter API would not output this, because it would break every conforming JSON consumer. Twitter API 不会输出这个,因为它会破坏每个符合标准的 JSON 消费者。

  • jsonlint shows the first, obvious syntax error: single-quoted rather than double quoted strings. jsonlint显示了第一个明显的语法错误:单引号而不是双引号字符串。
  • Secondly, you have None where JSON requires null , False instead of false , and True , instead of true .其次,您有None ,其中 JSON 需要nullFalse代替falseTrue代替true

Your alleged "JSON" example appears to have been pre-decoded into Python :).您所谓的“JSON”示例似乎已被预解码为 Python :)。 When I use a snippet of real JSON, it works exactly as expected:当我使用一段真实的 JSON 时,它的工作原理完全符合预期:

import json

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

jason = json.loads(json_string)

print(jason[0]["actual_json_key"])

I did json.loads(json.loads(string)) and was able to get the dictionary.我做了json.loads(json.loads(string))并且能够得到字典。 You can check it out.你可以检查一下。 The first time it doesn't just return the same string, but processes it (eg removes \\ characters).第一次它不仅返回相同的字符串,而且处理它(例如删除\\字符)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM