如何让yfinance通过HTTP(S)或SOCKS5代理正常工作?
问题背景
现有两个代理服务:
- 2081端口提供HTTP(S)代理,浏览器配置后可正常访问Yahoo网站;
- 2080端口提供SOCKS5代理,通过curl命令可成功下载Yahoo金融数据:
url="https://query1.finance.yahoo.com/v7/finance/download/MSFT" curl --socks5-hostname 127.0.0.1:2080 $url -o msft.txt
但尝试三种方式让yfinance通过代理获取数据均失败,且SOCKS5代理稳定性优于HTTP(S)代理(HTTP(S)仅偶尔能成功),需解决yfinance通过SOCKS5代理正常获取数据的问题。
已尝试的失败方法及原因分析
方法1:直接在history方法指定代理
import yfinance as yf msft = yf.Ticker("MSFT") msft.history(proxy="http://127.0.0.1:2081") msft.history(proxy="https://127.0.0.1:2081") msft.history(proxy="socks5://127.0.0.1:2080")
失败原因:yfinance的proxy参数对SOCKS5代理支持不完善,仅适配HTTP/HTTPS代理格式。
方法2:设置系统环境变量代理
cd ~ export all_proxy=socks5://127.0.0.1:2080 python3
进入Python环境后执行:
import yfinance as yf msft = yf.Ticker("MSFT") msft.history()
失败原因:默认请求库未正确处理SOCKS5代理的DNS解析,且默认10秒超时时间过短,易触发连接超时。
方法3:Pysocks全局设置代理
# pip install Pysocks first import socket import socks socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 2080) socket.socket = socks.socksocket import yfinance as yf msft = yf.Ticker("MSFT") msft.history()
失败原因:未开启远程DNS解析(对应curl的--socks5-hostname参数),本地解析Yahoo域名失败,导致无法建立连接。
解决方案
方案1:修正Pysocks配置,开启远程DNS解析
针对方法3的问题,在设置代理时添加rdns=True参数,让代理服务器处理域名解析,同时延长超时时间:
import socket import socks # 开启远程DNS解析,对应curl的--socks5-hostname socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 2080, rdns=True) socket.socket = socks.socksocket import yfinance as yf msft = yf.Ticker("MSFT") # 延长超时时间至30秒,适配代理网络延迟 data = msft.history(period="1mo", timeout=30) print(data)
方案2:用requests+socks适配器替换yfinance底层请求
安装依赖:
pip install requests[socks]
通过自定义requests session配置SOCKS5代理,替换yfinance的默认请求会话:
import yfinance as yf import requests from requests.adapters import HTTPAdapter from urllib3.contrib.socks import SOCKS5Adapter # 创建会话并挂载SOCKS5适配器,开启远程DNS解析 session = requests.Session() session.mount("http://", SOCKS5Adapter("127.0.0.1", 2080, rdns=True)) session.mount("https://", SOCKS5Adapter("127.0.0.1", 2080, rdns=True)) # 替换yfinance的默认会话 yf.shared._SESSION = session msft = yf.Ticker("MSFT") data = msft.history(period="1mo", timeout=30) print(data)
方案3:环境变量+requests适配器结合
设置支持远程DNS解析的SOCKS5环境变量:
export ALL_PROXY=socks5h://127.0.0.1:2080 # socks5h表示由代理处理DNS解析 python3
在Python中配置会话:
import yfinance as yf import requests from requests.adapters import HTTPAdapter from urllib3.contrib.socks import SOCKS5Adapter session = requests.Session() session.mount("http://", SOCKS5Adapter()) session.mount("https://", SOCKS5Adapter()) yf.shared._SESSION = session msft = yf.Ticker("MSFT") data = msft.history(period="1mo", timeout=30) print(data)
注意事项
- 超时时间:代理网络存在延迟时,建议将
timeout参数设置为20-30秒,避免频繁触发超时错误; - DNS解析:必须使用远程DNS解析(
rdns=True或socks5h协议),否则本地解析Yahoo域名可能失败; - 依赖检查:确保已安装
pysocks或requests[socks],否则无法处理SOCKS5代理请求。
内容的提问来源于stack exchange,提问作者showkey
相关产品推荐
相关产品推荐

