はじめに
最近、yfinance.download()(以下、「yf.download()」と言う)でYFRateLimitErrorというエラーがでるようになり株価の取得ができなくなりました。エラーを回避する方法について調べたことをまとめました。
環境
MacBook Air
macOS Sequoia 15.4.1
python 3.7.6
経緯
自分はPythonを使ってARKKとARKXという2つのETFの組み入れ銘柄の株価情報を取得、編集してTreemapや騰落率をXにポストしています。
ところが最近株価情報取得のために使っているyfinance.download()でYFRateLimitErrorというエラーが出るようになり、株価情報が取得できなくなりました。
1 Failed download:
['ARKK']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')
アクセスが集中して一時的に制限をかけてるのかなと思い、時間を置いてアクセスしたり、タイマーを使って間隔をあけてダウンロードするようにしてみたのですがエラーは解消しませんでした。
yfinanceをアップグレードすればエラーは解消するというポストを見かけましたが、自分yfinanceは最新版でした笑
対応
調べたところgithub issuesにYFRateLimitErrorを回避する方法としてcurl_cffiというライブラリを使いyf.download()をyf.Ticker(..., session=session).history(...) に置き換える方法が共有されていることがわかりました。
Issues:YFrateLimitError
yf.Tickerを使って回避する方法
修正コード
import yfinance as yf
from curl_cffi import requests
session = requests.Session(impersonate="safari15_5")
# yf.download(tickers=name, progress=False)をいかに置き換える
ticker_obj = yf.Ticker(name, session=session)
data = ticker_obj.history(period="5d", interval="1d")
コードの説明
まず、必要なライブラリ(curl_cffi)をインストールします。
pip install curl_cffi --upgrade
1.ライブラリをインポートします。
import yfinance as yf
from curl_cffi import requests
• yfinance: Yahoo Finance から株価データを取得するライブラリ。
• curl_cffi: Pythonから「本物のブラウザ(SafariやChrome)」を偽装したリクエストを送れるライブラリ。
2.curl_cffiセッションを作成します。
session = requests.Session(impersonate="safari15_5")
• 「Safari 15.5」ブラウザを偽装したセッションを作成。
• これにより、YahooにSafariでアクセスしているように見せています。
【注】impersonateにサポートされていないブラウザを指定するとエラーになります。
['ARKK']: RequestsError('impersonate chrome is not supported')
サポートされているブラウザーは下記を参照
3.Tickerオブジェクトを作成します。
ticker_obj = yf.Ticker(name, session=session)
• name というティッカー(例:"AAPL"、"ARKK")に対応する Tickerオブジェクト を作成。
• セッションを明示的に指定 することで、yfinance が curl_cffi 経由でYahooにアクセスするようにします。
4.株価データを取得します。
data = ticker_obj.history(period="5d", interval="1d")
• 指定したティッカーについて 過去5日間の1日ごとの株価データ(日足) を取得。
• period="5d": 直近5営業日。
• interval="1d": 1日ごとのデータ(終値、始値、高値、安値、出来高など)。
5.yf.download(tickers=name) → yf.Ticker(ticker, session=session).history(...) に変更します。
# 旧
data = yf.download(tickers=name, progress=False) # nameはティッカー
# 新
ticker_obj = yf.Ticker(name, session=session)
data = ticker_obj.history(period="5d", interval="1d") # 例:過去5日の日足データ
curl_cffiのドキュメント
以下について記載されているポスト
・curl_cffi セッションでレート制限を回避しながら株価データを取得
・取得済みデータをキャッシュし、繰り返しリクエストを最小化して高速化・負荷軽減
https://x.com/stocksprofesso/status/1918120070527774902