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

Python遍历字典列表提取Binance数据报TypeError如何解决

错误原因

触发TypeError: unhashable type: 'dict'的核心问题是循环逻辑编写错误:

  • data['symbols']本身是字典组成的列表,写for i in data['symbols']时,每次遍历拿到的i就是单个交易对的字典对象,不是列表下标、也不是交易对名称字符串
  • 后续代码写data[i]['status'],相当于把整个字典作为键去索引data对象,而字典是不可哈希类型,不能作为字典的键使用,因此直接抛出类型错误
  • 后续拼接成交记录查询URL时直接拼接i的写法也有问题,字典类型无法和字符串直接拼接,就算前面的索引不报错,走到这一步也会触发新的异常
修正逻辑

要顺利完成采集需要调整3个核心点:

  • 遍历data['symbols']时,直接从每个遍历到的交易对字典对象中读取status和symbol字段,不需要额外用遍历值去索引外层data
  • 查询非活跃交易对的成交记录时,传参使用交易对的symbol字符串值,拿到返回结果后取最新一条记录的time字段(毫秒级时间戳,可转换为标准日期格式)
  • 增加基础的请求异常处理、接口限频控制,避免请求过快被平台拦截,同时将采集结果正确写入CSV文件

修正后的可运行代码如下:

import requests
import csv
import time
from datetime import datetime

# 接口地址配置
exchange_info_url = 'https://api.binance.com/api/v3/exchangeInfo'
recent_trade_url = 'https://api.binance.com/api/v3/trades'

# 拉取全量交易对基础信息
resp = requests.get(exchange_info_url, timeout=10)
resp.raise_for_status()
exchange_data = resp.json()
all_symbols = exchange_data['symbols']

# 初始化输出文件,写入表头
output_path = r'C:\Users\Utilisateur\Desktop\binance_market_status.csv'
with open(output_path, 'w', encoding='utf-8', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(["symbol", "status", "last_trade_time"])

# 逐个遍历交易对
for symbol_info in all_symbols:
    symbol = symbol_info['symbol']
    status = symbol_info['status']
    last_trade_time = ""

    # 对非交易状态的交易对,查询最后一笔成交时间
    if status != "TRADING":
        try:
            trade_resp = requests.get(
                recent_trade_url, 
                params={"symbol": symbol, "limit": 1}, 
                timeout=10
            )
            trade_resp.raise_for_status()
            trade_data = trade_resp.json()
            if trade_data:
                # 把毫秒级时间戳转换为标准日期格式
                ts = trade_data[0]['time'] / 1000
                last_trade_time = datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
            # 加请求间隔避免触发公开接口限频
            time.sleep(0.1)
        except Exception as e:
            last_trade_time = f"query failed: {str(e)}"
            print(f"交易对{symbol}成交记录查询失败: {e}")

    # 结果写入CSV
    with open(output_path, 'a', encoding='utf-8', newline='') as f:
        writer = csv.writer(f)
        writer.writerow([symbol, status, last_trade_time])
    
    print(f"已处理交易对{symbol}, 状态: {status}, 最后成交时间: {last_trade_time}")
补充说明
  • 代码使用params参数传递接口请求字段,避免手动拼接URL带来的特殊字符转义问题
  • 100ms的请求间隔符合公开接口单IP每秒20次请求的限频规则,不会被拦截
  • 兼容了成交记录为空、接口请求失败的异常场景,单个交易对查询失败不会中断整个采集任务
  • 输出文件额外保留了status字段,可直接区分暂停交易、退市等不同的非活跃状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:57:23