在国内通过代理访问 yfinance
近几年在强化学习基础理论方面花了好多时间,但因为没有实际项目经验,压根找不到相关工作。白瞎了这几年所花的金钱、时间和精力。
想找个项目来做做,需要硬件的玩不起,那就找个纯软件的吧。
FinRL 看起来不错,打算试一试。FinRL 是哥伦比亚大学团队开源的“金融强化学习一站式工具箱”,专门用来快速开发股票、加密货币、投资组合等自动化交易策略。
万事开头难,通过 Yahoo Finance 网页接口获取金融数据时总是报错:
YFRateLimitError: Too Many Requests. Rate limited. Try after a while.
用 yf.set_config() 配置了代理也没用,仍然报上述错误。
In [0]:
import yfinance as yf
import pandas as pd # 通常会用到 pandas
# 配置代理
yf.set_config({
"proxy": {
"http": "http://127.0.0.1:7890",
"https": "http://127.0.0.1:7890" # 通常代理服务器用http协议访问
}
})
# 创建一个代表苹果公司 (AAPL) 的 Ticker 对象
aapl = yf.Ticker("AAPL")
aapl_info = aapl.info
# 查看信息字典中的部分内容
print(f"公司名称: {aapl_info.get('longName', 'N/A')}")
print(f"所在行业: {aapl_info.get('industry', 'N/A')}")
print(f"所在板块: {aapl_info.get('sector', 'N/A')}")
Out [0]:
YFRateLimitError: Too Many Requests. Rate limited. Try after a while.
但是,通过 os.environ['HTTP_PROXY'] 配置代理,却可以正常获取数据。
In [1]:
import yfinance as yf
import pandas as pd # 通常会用到 pandas
# 配置代理
import os
proxy = 'http://127.0.0.1:7890' # 代理设置,此处修改
os.environ['HTTP_PROXY'] = proxy
os.environ['HTTPS_PROXY'] = proxy
# 创建一个代表苹果公司 (AAPL) 的 Ticker 对象
aapl = yf.Ticker("AAPL")
aapl_info = aapl.info
# 查看信息字典中的部分内容
print(f"公司名称: {aapl_info.get('longName', 'N/A')}")
print(f"所在行业: {aapl_info.get('industry', 'N/A')}")
print(f"所在板块: {aapl_info.get('sector', 'N/A')}")
Out [1]:
公司名称: Apple Inc.
所在行业: Consumer Electronics
所在板块: Technology
召唤豆包!
这两个代码的核心区别在于代理配置方式的不同,这导致了它们的执行结果存在差异。具体原因如下:
代理配置机制的差异:
- 方式一(第一个代码):
使用yf.set_config()设置代理,这是 yfinance 官方文档推荐的方法,但它只对 yfinance 库内部的请求生效。- 方式二(第二个代码):
通过设置系统环境变量HTTP_PROXY和HTTPS_PROXY,这种方式会对整个 Python 进程中的所有网络请求生效,包括 yfinance 依赖的底层库(如curl_cffi、requests等)。为什么第二个代码能正常工作?
yfinance 的底层实现依赖curl_cffi库进行网络请求,而curl_cffi更倾向于使用系统环境变量中的代理配置,而不是 yfinance 自身的set_config()配置。
当你通过环境变量设置代理时:
- 所有网络请求(包括 yfinance 内部的请求)都会自动使用这个代理
- 底层的curl_cffi库能正确识别并使用这些代理设置
- 代理配置更彻底,不会出现部分请求未使用代理的情况
第一个代码失败的可能原因
yfinance 的set_config()方法在处理代理时可能存在以下问题:
- 版本兼容性问题:某些 yfinance 版本中,set_config()的代理设置可能存在 bug
- 覆盖不完整:可能无法覆盖所有底层库的请求(特别是curl_cffi)
- 代理协议不匹配:yfinance 内部可能对代理协议有特殊要求
开整吧!