BNB 历史数据 · 时间段抓取
简介 —— 这段 Python 脚本通过币安公开 API,按时间段循环抓取 BNB/USDT 从 2017-01-01 至 2026-09-22 的全部日线数据。使用 while 循环配合 startTime 分页拉取,最终合并为完整的 DataFrame 并保存为 CSV 文件。适合做长期历史回测或数据分析。
1. 导入所需库
只需要两个库:网络请求与数据处理。
import requests
import pandas as pd
- requests — 发送 HTTP 请求,获取币安 API 数据
- pandas — 处理时间戳、构建 DataFrame、保存 CSV
2. 接口配置 & 时间范围
时间戳转换 — 使用 pd.Timestamp().timestamp() * 1000 将日期转为毫秒级 Unix 时间戳。
url = "https://api.binance.com/api/v3/klines"
start_ts = int(pd.Timestamp("2017-01-01").timestamp() * 1000)
end_ts = int(pd.Timestamp("2026-09-22 23:59:59").timestamp() * 1000)
- url — 币安 K 线公开端点
- start_ts — 起始时间 2017-01-01
- end_ts — 结束时间 2026-09-22 23:59:59
3. 循环分页抓取数据
每次请求最多 3600 条,通过更新 current 实现逐段拉取。
all_data = []
current = start_ts
while current < end_ts:
params = {
"symbol": "BNBUSDT",
"interval": "1d",
"startTime": current,
"endTime": end_ts,
"limit": 3600
}
resp = requests.get(url, params=params)
data = resp.json()
if not data:
break
all_data.extend(data)
current = data[-1][0] + 86400000 # 下一天
- all_data — 累积所有请求结果
- symbol — BNBUSDT
- interval — 1d 日线
- limit=3600 — 单次最多 3600 条
- current = data[-1][0] + 86400000 — 最后一条开盘时间 + 一天毫秒数
4. 构建 DataFrame
df = pd.DataFrame(all_data, columns=[
"OpenTime", "Open", "High", "Low", "Close", "Volume",
"CloseTime", "QuoteVolume", "Trades", "TakerBuyBase", "TakerBuyQuote", "Ignore"
])
币安返回的每条数据包含 12 个字段,需手动指定列名。
5. 数据类型处理
df["Date"] = pd.to_datetime(df["OpenTime"], unit="ms")
for c in ["Open", "High", "Low", "Close", "Volume"]:
df[c] = df[c].astype(float)
df = df.set_index("Date")[["Open", "High", "Low", "Close", "Volume"]]
- 毫秒时间戳 → 可读日期
- 价格与成交量转为浮点数
- 只保留 Open, High, Low, Close, Volume
- 将 Date 设为索引
6. 打印预览 & 保存 CSV
print(df.head())
print(df.tail())
print(df.describe())
df.to_csv("bnb_2017_2026.csv", encoding="utf-8-sig")
print("✅ 已保存到 bnb_2017_2026.csv")
提示 — encoding="utf-8-sig" 确保 CSV 在 Excel 中打开不乱码。
- df.head() — 前 5 行
- df.tail() — 最后 5 行
- df.describe() — 统计概览
完整代码
import requests
import pandas as pd
url = "https://api.binance.com/api/v3/klines"
start_ts = int(pd.Timestamp("2017-01-01").timestamp() * 1000)
end_ts = int(pd.Timestamp("2026-09-22 23:59:59").timestamp() * 1000)
all_data = []
current = start_ts
while current < end_ts:
params = {
"symbol": "BNBUSDT",
"interval": "1d",
"startTime": current,
"endTime": end_ts,
"limit": 3600
}
resp = requests.get(url, params=params)
data = resp.json()
if not data:
break
all_data.extend(data)
current = data[-1][0] + 86400000 # 下一天
df = pd.DataFrame(all_data, columns=[
"OpenTime", "Open", "High", "Low", "Close", "Volume",
"CloseTime", "QuoteVolume", "Trades", "TakerBuyBase", "TakerBuyQuote", "Ignore"
])
df["Date"] = pd.to_datetime(df["OpenTime"], unit="ms")
for c in ["Open", "High", "Low", "Close", "Volume"]:
df[c] = df[c].astype(float)
df = df.set_index("Date")[["Open", "High", "Low", "Close", "Volume"]]
print(df.head())
print(df.tail())
print(df.describe())
df.to_csv("bnb_2017_2026.csv", encoding="utf-8-sig")
print("✅ 已保存到 bnb_2017_2026.csv")
关键点总结
毫秒时间戳精准控制起止
while 循环分页拉取
current = data[-1][0] + 86400000
all_data.extend() 累积结果
保存为 bnb_2017_2026.csv
保留所有原始注释