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
相关产品推荐
相关产品推荐

