跳转至

通过eia.gov的API接口获取数据

获取 API Key

通过eia.gov 的 这个网址 可以通过API获取各种能源数据。

要使用API,首先你要注册获取一个 API Key

点击网页右侧的 REGISTER按钮去注册,按照要求填写提交后,点击收到的激活链接,API Key 会发送到你注册填写的邮箱中,

一个示例

根据这里的API接口描述, 可以大概知道 这个服务 的 APIv2 的请求格式

如果看文档还不是特别清楚,可以用一个 电力数据获取 的案例来 理解。

点击打开这个电力数据网址


按 F12 打开开发者工具栏,点击 Network tab 页, 然后点击 Submit ,从网页发出请求,

可以发现 捕获到的 API请求和相应 消息。 点击就可以查看具体的数据和格式。

可以发现请求参数 在 HTTP header 里面的 X-Params 这个请求头里面设置。


知道了格式,我们要使用Python 发送HTTP请求,该怎么做呢?

当然使用非常有名的 Requests库。

关于如何使用该库构建 Http请求,获取响应中的数据,具体可以看我的这个教程链接


我们可以这样定义一个函数和调用它的代码

from ak import apiKey # the apikey is in another file
import requests, json
import pandas as pd

def getData(apiKey, route, xParams):
    url = "https://api.eia.gov" + route + "?api_key=" + apiKey

    response = requests.get(url,headers={
        'X-Params' : json.dumps(xParams)
    })

    df = pd.DataFrame(response.json()["response"]['data'])

    return df

df = getData(apiKey, 
    "/v2/electricity/rto/region-data/data/",
    {
        "frequency": "hourly",
        "data": [
            "value"
        ],
        "facets": {},
        "start": "2024-03-11T00",
        "end": "2024-03-11T00",
        "sort": [
            {
                "column": "period",
                "direction": "desc"
            }
        ],
        "offset": 0,
        "length": 5000
    }
)    

pd.options.display.width = 500
pd.options.display.max_columns = None
pd.options.display.max_rows = None

df = pd.DataFrame(df)
print(df)


如果我们只想获取其中 一天需求量预估,可以使用过滤条件,如下

df2 = df[df["type-name"] == "Day-ahead demand forecast"]


如果我们想根据 需求量预估 的值 进行排序, 很容易想到会这样写

df2.sort_values(by='value')  

但是你会发现结果不对,没有排序

看看列数据的类型,

In [30]: df2.dtypes
Out[30]:
period             object
respondent         object
respondent-name    object
type               object
type-name          object
value              object
value-units        object
dtype: object

原来 value 不是数字类型,而是 object 类型,所以不好排序


可以先转换类型再排序,这样

df3 = df2.astype({'value' : float}).sort_values(by='value')


plot 柱状图

import matplotlib.pyplot as plt

p = df3.plot(x='respondent', y='value' , kind='bar')

plt.show()


可以这样设置图片的宽度/高度

# 宽度20inch,高度 6 inch
plt.rcParams["figure.figsize"] = (20,6)
p = df3.plot(x='respondent', y='value' , kind='bar')
plt.show()


可以这样让plot柱状图 bar顶部带刻度

plt.rcParams["figure.figsize"] = (30,6)
ax = df3.plot.bar(x='respondent', y='value')
ax.bar_label(ax.containers[0])

plt.show()