Coingecko API触发KeyError: 'prices'问题求助
修复方案
核心问题分析
你遇到的KeyError: 'prices'本质是CoinGecko API调用超限,此时API返回的不是正常包含prices字段的JSON,而是限流提示,直接取['prices']自然报错。即使修改days参数,只要调用频率超限,问题依旧存在。
具体修复步骤
1. 添加请求异常与响应校验
不要直接链式调用.json()['prices'],先检查请求状态码,再校验返回的JSON结构:
import requests from flask import render_template, abort @app.route('/') def cryptodashboard(): # 封装API请求函数,统一处理异常 def fetch_market_data(coin_id, days=30): url = f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart?vs_currency=usd&days={days}" try: response = requests.get(url, headers={"User-Agent": "CryptoDashboard/1.0"}) response.raise_for_status() # 抛出HTTP错误(4xx/5xx) data = response.json() if 'prices' not in data: raise ValueError("API返回数据格式异常") return data['prices'] except (requests.exceptions.RequestException, ValueError) as e: print(f"获取{coin_id}数据失败: {str(e)}") abort(503) # 返回服务不可用状态码 def fetch_live_data(coin_id): url = f"https://api.coingecko.com/api/v3/coins/{coin_id}" try: response = requests.get(url, headers={"User-Agent": "CryptoDashboard/1.0"}) response.raise_for_status() data = response.json() if 'market_data' not in data: raise ValueError("API返回数据格式异常") return data except (requests.exceptions.RequestException, ValueError) as e: print(f"获取{coin_id}实时数据失败: {str(e)}") abort(503) # 获取数据 btc_data = fetch_market_data('bitcoin', days=30) eth_data = fetch_market_data('ethereum', days=30) xrp_data = fetch_market_data('ripple', days=30) btc_live = fetch_live_data('bitcoin') eth_live = fetch_live_data('ethereum') xrp_live = fetch_live_data('ripple') # 提取市值 btc_market_cap = btc_live['market_data']['market_cap']['usd'] eth_market_cap = eth_live['market_data']['market_cap']['usd'] xrp_market_cap = xrp_live['market_data']['market_cap']['usd'] return render_template('index.html', btc_data=btc_data, eth_data=eth_data, xrp_data=xrp_data, btc_live=btc_live, eth_live=eth_live, xrp_live=xrp_live, btc_market_cap=btc_market_cap, eth_market_cap=eth_market_cap, xrp_market_cap=xrp_market_cap)
2. 启用数据缓存,减少API调用
免费版CoinGecko API有调用频率限制(每分钟约50次),页面频繁刷新会快速超限。可以用Flask-Caching缓存API响应,比如缓存5分钟:
from flask_caching import Cache # 初始化缓存 cache = Cache(app, config={'CACHE_TYPE': 'SimpleCache', 'CACHE_DEFAULT_TIMEOUT': 300}) # 给数据获取函数添加缓存装饰器 @cache.cached() def fetch_market_data(coin_id, days=30): # 原函数内容不变 pass @cache.cached() def fetch_live_data(coin_id): # 原函数内容不变 pass
3. 合并API请求,减少调用次数
CoinGecko支持批量查询,用/coins/markets接口一次性获取多个币种的实时数据,替代三次单独请求:
def fetch_batch_live_data(): url = "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=bitcoin,ethereum,ripple" try: response = requests.get(url, headers={"User-Agent": "CryptoDashboard/1.0"}) response.raise_for_status() data = response.json() # 整理成字典方便后续调用 return {item['id']: item for item in data} except requests.exceptions.RequestException as e: print(f"批量获取实时数据失败: {str(e)}") abort(503) # 使用时: live_data = fetch_batch_live_data() btc_live = live_data['bitcoin'] eth_live = live_data['ethereum'] xrp_live = live_data['ripple']
4. 调整请求参数与策略
- 降低
days参数:比如用30天替代365天,减少单请求的数据量,降低API负载 - 前端添加防抖或设置自动刷新间隔:避免页面短时间内频繁刷新触发API请求
内容的提问来源于stack exchange,提问作者noobcodersan
相关产品推荐
相关产品推荐

