首页 > 解决方案 > Python中的JSON数组keyerror

问题描述

我对 Python 编程相当陌生,正在尝试从 JSON 数组中提取数据。下面的代码导致错误

js[jstring][jkeys]['5. volume'])

任何帮助将非常感激。

import urllib.request, urllib.parse, urllib.error
import json

def DailyData(symb):

    url = https://www.alphavantage.co/queryfunction=TIME_SERIES_DAILY&symbol=MSFT&apikey=demo

    stockdata = urllib.request.urlopen(url)
    data = stockdata.read().decode()

    try:
        js = json.loads(data)
    except:
        js = None

    jstring = 'Time Series (Daily)'

    for entry in js:
        i = js[jstring].keys()

        for jkeys in i:
            return (jkeys,
                js[jstring][jkeys]['1. open'],
                js[jstring][jkeys]['2. high'],
                js[jstring][jkeys]['3. low'],
                js[jstring][jkeys]['4. close'],
                js[jstring][jkeys]['5. volume'])

print('volume',DailyData(symbol)[5])

标签: arraysjsonpython-3.xfunction

解决方案


看起来错误的原因是因为从 URL 返回的数据比您可能意识到的更具层次性。要看到这一点,打印出 js(我推荐使用 jupyter notebook):

import urllib.request, urllib.parse, urllib.error
import ssl
import json
import sqlite3

url = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&apikey=demo"

stockdata = urllib.request.urlopen(url)
data = stockdata.read().decode()

js = json.loads(data)
js

在此处输入图像描述

您可以看到 js(现在是 python dict)在实际时间序列开始之前有一个“元数据”键。您需要在该键处开始对 dict 进行操作。

话虽如此,要将数据放入类似结构的表中(用于绘图、时间序列分析等),您可以使用 pandas 包将 dict 键直接读入数据框。pandas DataFrame 构造函数接受一个字典作为输入。在这种情况下,数据被转置,所以最后的 T 旋转它(尝试使用和不使用 T,你会看到它。

import pandas as pd

df=pd.DataFrame(js['Time Series (Daily)']).T 

df

在此处输入图像描述

添加了编辑...您可以使用一行代码将数据放入数据框中:

import requests
import pandas as pd

url = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&apikey=demo"

data = pd.DataFrame(requests.get(url).json()['Time Series (Daily)']).T

DataFrame:来自 Pandas 的构造函数,用于将数据制作成表格状结构

requests.get():从请求库中获取数据的方法。

.json():直接从 JSON 转换为 dict

['Time Series (Daily)']: 从dict中取出key就是时间序列

.T:转置行和列。

在此处输入图像描述

祝你好运!

以下代码对我有用

import urllib.request, urllib.parse, urllib.error
import json

def DailyData(symb):

    # Your code was missing the ? after query
    url = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={}&apikey=demo".format(symb)

    stockdata = urllib.request.urlopen(url)
    data = stockdata.read().decode()

    js = json.loads(data)

    jstring = 'Time Series (Daily)'

    for entry in js:
        i = js[jstring].keys()

        for jkeys in i:
            return (jkeys,
                js[jstring][jkeys]['1. open'],
                js[jstring][jkeys]['2. high'],
                js[jstring][jkeys]['3. low'],
                js[jstring][jkeys]['4. close'],
                js[jstring][jkeys]['5. volume'])

# query multiple times, just to print one item?
print('open',DailyData('MSFT')[1])
print('high',DailyData('MSFT')[2])
print('low',DailyData('MSFT')[3])
print('close',DailyData('MSFT')[4])
print('volume',DailyData('MSFT')[5])

输出:

打开 99.8850

高 101.4300

低点 99.6700

收盘价 101.1600

卷 19234627

如果没有看到错误,很难知道您遇到了什么确切的问题。


推荐阅读