OKEX API V1 与 V3 对比:Python 报错“If using all scalar values, you must pass an index”的终极解决

·

在对接 OKEX API 抓取比特币实时行情时,许多开发者都会被一串让人抓狂的报错拦住去路:

ValueError: If using all scalar values, you must pass an index

表面看像是代码错误,折腾几小时后才恍然大悟——症结不在代码,而在于 API 版本差异。本文以案例形式拆解 V1 与 V3 接口设计、字段类型、索引差异 三大关键点,并提供可直接复制运行的 Python 模板,帮你 3 分钟打通数据采集 pipeline。


报错的幕后真相

当你用 Pandas 的 pd.DataFrame() 展开 OKEX 返回的 JSON,而返回体恰好是 纯标量值 而缺少 列表结构 时,Pandas 会拒绝直接生成 DataFrame,于是抛出标题中的 ValueError。
OKEX V3 接口常犯此“毛病”;V1 则不会。原因如下:

维度V1 接口V3 接口
返回形态纯数值列表键值对甚至还有字符串
可做强制dtype='float' 有效遇到字符串时强制失败
DataFrame自动扩维无需手动 index必须手动加 index=[0] 解决

两分钟快速修复方案

✅ 方案 A:退而求稳,改用 V1

import requests, pandas as pd, json, time

symbol = 'BTC-USD'                         # 任何交易对
url = f'https://www.okex.com/api/v1/ticker.do?symbol={symbol}'
res = requests.get(url, timeout=10)
data = res.json()['ticker']
df = pd.DataFrame(data, dtype='float', index=[0])  # 直接成功
print(df.head())
优点:一次成型,字段全是数值。
局限:V1 官方标记为“旧版”,未来可能下线。

👉 查看同步脚本,一键替换 V1 获取最稳定的比特币实时数据

✅ 方案 B:拥抱 V3,多做 20% 处理

import requests, pandas as pd

symbol = 'BTC-USD'
url = f'https://www.okx.com/join/8265080api/spot/v3/instruments/{symbol}/ticker'
res = requests.get(url, timeout=10)
data = res.json()

# 关键两行:保留混合数据类型 & 手动加 index
df = pd.DataFrame([data])        # 不要 dtype='float'
print(df.head())

注意点

  1. 若后续需要数值计算,对特定列再 astype(float) 即可。
  2. 生产环境中建议加 try-except 捕捉网络异常,降低中断风险。

FAQ:高频问答

Q1 : 官方文档哪一章提及 V1 下线计划?
A1:目前官网仅在 CDN 边缘注释“Legacy Version”。建议将核心策略迁移至 V3,但过渡期依赖 V1 仍可稳定使用。

Q2 : V3 接口为何返回字符串?能改吗?
A2:V3 引入 last, high_24h, vol_ccy 等多币种单位字段,有的值默认带千分位格式。这是官方设计,无法通过参数关闭,只能在本地强制转型。

Q3 : 如果想一次获取多个交易对,是否需要循环?
A3:是,OKEX 的 ticker 端点一次只对一个 symbol;多对行情可并发协程,或订阅 WebSocket 流推送。

Q4 : index=[0] 会不会影响后续 merge?
A4:仅作用于当前行,后续追加数据建议用 df = pd.concat([df, new_df], ignore_index=True) 回归自然递增索引。

Q5 : 有没有零代码方式体验 V3?
A5:可以在浏览器直接 GET https://www.okx.com/join/8265080api/spot/v3/instruments/BTC-USD/ticker 查看 JSON 结构。


实战示例:V3 输出清洗合一函数

def okex_v3_ticker(symbol: str):
    """
    返回字段清洗后的 DataFrame,所有数值列统一转为 float
    """
    url = f'https://www.okex.com/api/spot/v3/instruments/{symbol}/ticker'
    res = requests.get(url, timeout=5)
    raw = res.json()

    # 清洗策略:简单转换 + 单位处理
    df = pd.DataFrame([raw])
    num_cols = ['last', 'bid', 'ask', 'high_24h', 'low_24h',
                'vol_24h', 'vol_ccy_24h']
    for col in num_cols:
        if col in df.columns:
            df[col] = df[col].astype(float)
    return df

调用示例:

btc_df = okex_v3_ticker('BTC-USD')

👉 复制粘贴即可跑通,抢先体验完整数据清洗流程


小结:版本决策 checklist

把上面三步文件丢进 Git,下次再也不怕 “If using all scalar values, you must pass an index” 拦路抢劫