python-binance get_historical_klines时间参数使用及报错解决
问题背景

调用币安SDK的get_historical_klines方法拉取BTCUSDT的1分钟K线时,传入计算得到的2天前的时间作为start_str参数触发报错,删除start_str、end_str参数后函数可正常运行,需要确认时间参数的正确传法。
原测试代码:
now = datetime.now() past = now - timedelta(days=2) past = str(past) bars = client.get_historical_klines("BTCUSDT", "1m", start_str = past, end_str = None, limit = 1000)
报错信息
TypeError: Input type must be str Traceback (most recent call last): File In [46], line 1 bars = client.get_historical_klines(symbol="BTCUSDT", interval="1m", start_str=past, end_str=None, limit=1000) File ~/opt/anaconda3/lib/python3.9/site-packages/binance/client.py:934, in Client.get_historical_klines return self._historical_klines(symbol, interval, start_str=start_str, end_str=end_str, limit=limit, klines_type=klines_type) File ~/opt/anaconda3/lib/python3.9/site-packages/binance/client.py:969, in Client._historical_klines start_ts = convert_ts_str(start_str) File ~/opt/anaconda3/lib/python3.9/site-packages/binance/helpers.py:76, in convert_ts_str return date_to_milliseconds(ts_str) File ~/opt/anaconda3/lib/python3.9/site-packages/binance/helpers.py:24, in date_to_milliseconds d = dateparser.parse(date_str, settings={'TIMEZONE': "UTC"}) File ~/opt/anaconda3/lib/python3.9/site-packages/dateparser/date.py:419, in DateDataParser.get_date_data raise TypeError('Input type must be str')
原因说明
- 直接调用
str()转换datetime对象得到的字符串格式类似2024-05-20 14:30:00.123456,带6位微秒后缀,部分版本的dateparser解析这类非标准时间格式时会出现类型判断异常,触发上述报错。 - 如果用本地时间
datetime.now()生成时间,还会存在时区偏差问题——币安接口默认用UTC时区,本地时区如果是东八区,直接传本地时间会导致拉取的K线起始时间差8小时。 - 查SDK源码可知,
start_str/end_str两个参数除了字符串,还支持直接传入整数类型的毫秒级Unix时间戳,传入整数时会直接跳过字符串解析逻辑,完全不会出现格式兼容问题,是生产环境首选的传参方式。
可运行示例代码
方案1:传入毫秒时间戳(推荐,无解析风险)
from datetime import datetime, timedelta from binance.client import Client # 初始化客户端,替换为自己的API密钥 client = Client(api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET") # 统一用UTC时间计算,避免时区偏差 utc_now = datetime.utcnow() start_time = utc_now - timedelta(days=2) # 转换为毫秒级Unix时间戳,整数类型 start_ts = int(start_time.timestamp() * 1000) bars = client.get_historical_klines( symbol="BTCUSDT", interval=Client.KLINE_INTERVAL_1MINUTE, start_str=start_ts, limit=1000 )
方案2:传入标准格式时间字符串
如果需要传字符串,手动指定时间格式输出不带微秒的UTC时间字符串即可,不要直接用str()转datetime:
from datetime import datetime, timedelta from binance.client import Client client = Client(api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET") start_time = datetime.utcnow() - timedelta(days=2) # 手动指定标准时间格式 start_str = start_time.strftime("%Y-%m-%d %H:%M:%S") bars = client.get_historical_klines( symbol="BTCUSDT", interval="1m", start_str=start_str, limit=1000 )
补充:该SDK也支持传入自然语言时间字符串比如
"2 days ago UTC"作为参数,但这种写法依赖dateparser的解析能力,不同依赖版本可能出现兼容问题,不建议生产环境使用。
内容的提问来源于stack exchange,提问作者Kyungyun Lee
相关产品推荐
相关产品推荐

