访问JSON元素

时间:2013-04-21 09:19:06

标签: python json

我从网址获取天气信息。

weather = urllib2.urlopen('url')
wjson = weather.read()

我得到的是:

{
  "data": {
     "current_condition": [{
        "cloudcover": "0",
        "humidity": "54",
        "observation_time": "08:49 AM",
        "precipMM": "0.0",
        "pressure": "1025",
        "temp_C": "10",
        "temp_F": "50",
        "visibility": "10",
        "weatherCode": "113",
        "weatherDesc": [{
            "value": "Sunny"
        }],
        "weatherIconUrl": [{
            "value": "http:\/\/www.worldweatheronline.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png"
        }],
        "winddir16Point": "E",
        "winddirDegree": "100",
        "windspeedKmph": "22",
        "windspeedMiles": "14"
    }]        
 }
}

如何访问我想要的任何元素?

如果我这样做:print wjson['data']['current_condition']['temp_C']我收到错误说:

  

字符串索引必须是整数,而不是str。

8 个答案:

答案 0 :(得分:82)

import json
weather = urllib2.urlopen('url')
wjson = weather.read()
wjdata = json.loads(wjson)
print wjdata['data']['current_condition'][0]['temp_C']

你从网址得到的是一个json字符串。并且您无法直接使用索引解析它。 您应该通过json.loads将其转换为dict,然后您可以使用索引对其进行解析。

不是使用.read()将其中间保存到内存中,然后将其读取到json,而是允许json直接从文件中加载它:

wjdata = json.load(urllib2.urlopen('url'))

答案 1 :(得分:22)

以下是使用requests的替代解决方案:

import requests
wjdata = requests.get('url').json()
print wjdata['data']['current_condition'][0]['temp_C']

答案 2 :(得分:4)

'temp_C'是字典内的一个键,位于字典

中的列表中

这种方式有效:

wjson['data']['current_condition'][0]['temp_C']
>> '10'

答案 3 :(得分:1)

仅提供一种选择...您也可以通过这种方式做到这一点:

MYJSON = {
    'username': 'gula_gut',
    'pics': '/0/myfavourite.jpeg',
    'id': '1'
}

#changing username
MYJSON['username'] = 'calixto'
print(MYJSON['username'])

我希望这会有所帮助。

答案 4 :(得分:1)

我做这个方法是为了一个 Json 的深度导航

def filter_dict(data: dict, extract):
    try:
        if isinstance(extract, list):
            while extract:
                if result := filter_dict(data, extract.pop(0)):
                    return result
        shadow_data = data.copy()
        for key in extract.split('.'):
            if str(key).isnumeric():
                key = int(key)
            shadow_data = shadow_data[key]
        return shadow_data
    except (IndexError, KeyError, AttributeError):
        return None

filter_dict(wjdata, 'data.current_condition.0.temp_C')
# 10

Using the multiple fields:
filter_dict(wjdata, ['data.current_condition.0.temp_C', 'data.current_condition.1.temp_C']) This working as a OR when take the first element found

# 10

答案 5 :(得分:0)

将get方法用于请求的另一种替代方法:

import requests
wjdata = requests.get('url').json()
print wjdata.get('data').get('current_condition')[0].get('temp_C')

答案 6 :(得分:0)

elm make Main.elm --output elm.js

答案 7 :(得分:0)

就像其他答案所指出的那样,这个问题的公认答案似乎忽略了原始海报对数据结构的误解。

主要问题似乎是原始解决方案纯粹将 JSON 视为字典,而实际上它是...

列表中的字典,字典中的字典,字典中的字典

因此, ['data'] 需要访问字典的顶级键值对, ['current_conditions'] 访问下一级字典, 那么 [0] 必须用于访问列表的第一个元素(只有 1 个元素)。

只有这样,['temp_C'] 才能用于访问该键的实际值并检索数据。

x={
  "data": {
            "current_condition": 
                [{
                    "cloudcover": "0",
                    "humidity": "54",
                    "observation_time": "08:49 AM",
                    "precipMM": "0.0",
                    "pressure": "1025",
                    "temp_C": "10",
                    "temp_F": "50",
                    "visibility": "10",
                    "weatherCode": "113",
                    "weatherDesc": 
                        [{
                            "value": "Sunny"
                        }],
                    
                    "weatherIconUrl": 
                        [{
                            "value": "http:\/\/www.worldweatheronline.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png"
                        }],
                    "winddir16Point": "E",
                    "winddirDegree": "100",
                    "windspeedKmph": "22",
                    "windspeedMiles": "14"
                },
                {
                    "cloudcover": "0",
                    "humidity": "54",
                    "observation_time": "08:49 AM",
                    "precipMM": "0.0",
                    "pressure": "1025",
                    "temp_C": "5",
                    "temp_F": "50",
                    "visibility": "10",
                    "weatherCode": "113",
                    "weatherDesc": 
                        [{
                            "value": "Sunny"
                        }],
                    
                    "weatherIconUrl": 
                        [{
                            "value": "http:\/\/www.worldweatheronline.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png"
                        }],
                    "winddir16Point": "E",
                    "winddirDegree": "100",
                    "windspeedKmph": "22",
                    "windspeedMiles": "14"
                }    ]        
            }
}


print(x['data']['current_condition'][0]['weatherDesc'][0]['value'])

# results in 'Sunny' 

在评论中回答另一个问题,

<块引用>

"有没有办法在不知道索引的情况下做到这一点,假设有 是否有更多当前条件条目?”

假设有多个 current_condition 条目,您不太可能只需要一个值,或者如果您这样做了,那么您可能会有另一条信息来定位该特定值(即位置或其他内容)。

>

假设您的数据集名为 x,即 x = {"data": ...}

如果您想要所有 current_condition 条目,您可以使用以下方法遍历(current_conditions)列表:

y = []

for index in range(0,len(x['data']['current_condition']))
   y.append(x['data']['current_condition'][index]['temp_C'])