You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中serde_json反序列化Binance API响应报错求助

Binance API 24小时行情反序列化错误解决

问题详情

调用Binance的/api/v1/ticker/24hr接口获取JSON数据,使用serde_json反序列化时触发错误:

Error("invalid type: map, expected a sequence", line: 1, column: 1)

接口返回的JSON结构(格式化后)

{  
  "symbol": "ETHBTC",
  "priceChange": "0.00068700",
  "priceChangePercent": "0.874",
  "weightedAvgPrice": "0.07908580",
  "prevClosePrice": "0.07864600",
  "lastPrice": "0.07933400",
  "lastQty": "0.18460000",
  "bidPrice": "0.07933400",
  "bidQty": "4.49640000",
  "askPrice": "0.07933500",
  "askQty": "54.13430000",
  "openPrice": "0.07864700",
  "highPrice": "0.07945000",
  "lowPrice": "0.07846100",
  "volume": "56892.20330000",
  "quoteVolume": "4499.36548634",
  "openTime": 1662288072375,
  "closeTime": 1662374472375,
  "firstId": 369847410,
  "lastId": 370015037,
  "count": 167628
}

原代码

use serde::Deserialize;
use std::error::Error;

#[derive(Deserialize, Debug)]
struct Peers {
    num: Vec<Peer>,
}

#[derive(Deserialize, Debug)]
struct Peer {
    symbol: String,
    count: u32,
}

fn get_node(url: &str) -> Result<Peer, Box<dyn Error>> {
    let response = ureq::get(url).call()?.into_string()?;
    let node: Peers = serde_json::from_str(&response)?;

    dbg!(node);
    todo!()
}

fn main() {
    let url = "https://api.binance.com/api/v1/ticker/24hr";
    let num = get_node(url);
    dbg!(num);
    todo!()
}

终端报错信息

num = Err(
    Error("invalid type: map, expected a sequence", line: 1, column: 1),
)
thread 'main' panicked at 'not yet implemented',
note: run with `RUST_BACKTRACE=1` environment variable to display a 

错误原因

  1. 原代码定义的Peers结构体期望JSON是包含num数组的对象(格式如{"num": [{}, {}]}),但Binance该接口实际返回的是单个交易对对象(不带symbol参数时返回所有交易对的数组),结构完全不匹配。
  2. 函数返回值定义为Result<Peer, ...>,但代码中反序列化的是Peers类型,类型不兼容。

修正方案

根据接口调用场景选择对应修正方式:

场景1:获取单个交易对的24小时行情

若接口URL指定了symbol参数(比如https://api.binance.com/api/v1/ticker/24hr?symbol=ETHBTC),直接将JSON反序列化为Peer结构体:

use serde::Deserialize;
use std::error::Error;

#[derive(Deserialize, Debug)]
struct Peer {
    symbol: String,
    count: u32,
    // 需使用其他字段时,在此添加对应定义
}

fn get_node(url: &str) -> Result<Peer, Box<dyn Error>> {
    let response = ureq::get(url).call()?.into_string()?;
    let node: Peer = serde_json::from_str(&response)?;

    dbg!(node);
    Ok(node)
}

fn main() {
    let url = "https://api.binance.com/api/v1/ticker/24hr?symbol=ETHBTC";
    let result = get_node(url);
    dbg!(result);
}

场景2:获取所有交易对的24小时行情

若调用不带symbol参数的接口,返回的是交易对象数组,需反序列化为Vec<Peer>:

use serde::Deserialize;
use std::error::Error;

#[derive(Deserialize, Debug)]
struct Peer {
    symbol: String,
    count: u32,
    // 需使用其他字段时,在此添加对应定义
}

fn get_nodes(url: &str) -> Result<Vec<Peer>, Box<dyn Error>> {
    let response = ureq::get(url).call()?.into_string()?;
    let nodes: Vec<Peer> = serde_json::from_str(&response)?;

    dbg!(nodes);
    Ok(nodes)
}

fn main() {
    let url = "https://api.binance.com/api/v1/ticker/24hr";
    let result = get_nodes(url);
    dbg!(result);
}

注意事项

  • 若需使用接口返回的其他字段,需在Peer结构体中添加对应字段定义,字段名需与JSON键完全一致(或通过#[serde(rename = "xxx")]重命名)。
  • 确保依赖已正确添加到Cargo.toml:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
ureq = "2.6"

内容的提问来源于stack exchange,提问作者Arunjot Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:36:29