Python株価取得コード集|yfinanceの実用サンプルとエラー対策

yfinanceで日本株・米国株を取得し、CSV保存、複数銘柄、差分更新、再試行まで実装するPythonコード集です。
このページは、Pythonで株価を取得するときに再利用できるコードを目的別にまとめたコード集です。単に取得するだけでなく、空データの検出、CSV保存、複数銘柄、再試行、ログまで扱います。
結論|目的別コード早見表
| やりたいこと | このページのコード | 重要な確認点 |
|---|---|---|
| 日本株を1銘柄取得 | yf.download("7203.T") | 日本株は通常、証券コードに.Tを付ける |
| Excelで開けるCSVを作る | encoding="utf-8-sig" | 日付をインデックスとして保存する |
| 複数銘柄を取得 | tickersへリストを渡す | MultiIndexの列構造を固定する |
| 毎日追記する | 既存CSVと新規データを結合 | 日付の重複を削除して並べ替える |
| 分足を日本時間で扱う | tz_convert("Asia/Tokyo") | 固定で9時間足す方法を避ける |
| 定期実行で落ちにくくする | 回数上限付き再試行 | 空データも失敗として記録する |
yfinanceを採用する理由と古い記事を見るときの注意
株価取得の記事にはyahoo_finance_api2を使う例もあります。日本株の.T指定、期間や足種の変更、DataFrameへの変換という考え方は参考になりますが、ライブラリ名、例外型、戻り値、対応状況は同じではありません。このコード集は、現在もドキュメントを確認でき、複数銘柄取得やDataFrame出力をまとめやすいyfinanceで統一します。
| 比較項目 | yfinance | yahoo_finance_api2の記事例 |
|---|---|---|
| 基本取得 | yf.download()・Ticker.history() | Share.get_historical() |
| 戻り値 | pandas DataFrame | 辞書をDataFrameへ変換する例がある |
| 日本株 | 7203.T | 同じく7203.Tの例がある |
| 時刻処理 | tz-awareならtz_convert() | UTCへ固定9時間を加える古い例がある |
| 本ページの扱い | 実行例を継続更新 | 移植時はAPI差分を確認 |
古いコードをそのまま混在させず、プロジェクト内では取得ライブラリを1種類に固定してください。
動作環境を準備する
Python 3.11以降を例にします。仮想環境を作り、必要なパッケージを導入します。
python -m venv .venv
.venv\\Scripts\\activate
python -m pip install --upgrade pip
python -m pip install yfinance pandasmacOS・Linuxでは有効化コマンドをsource .venv/bin/activateへ変更します。
再現できるよう、実行時のバージョンも記録します。
python -c "import sys, yfinance, pandas; print(sys.version); print(yfinance.__version__); print(pandas.__version__)"
python -m pip freeze > requirements-lock.txt1銘柄の日足を取得する
日本株は、一般に証券コードの後ろへ.Tを付けます。次の例はトヨタ自動車の直近1年分です。
import yfinance as yf
df = yf.download(
"7203.T",
period="1y",
interval="1d",
auto_adjust=True,
progress=False,
multi_level_index=False,
)
if df.empty:
raise RuntimeError("株価データを取得できませんでした")
print(df.tail())auto_adjust=Trueでは、分割や配当を考慮した調整後価格としてOHLCが返されます。未調整値が必要な分析では引数とデータ列を確認してください。
CSVへ文字化けせず保存する
Excelで開く可能性がある場合は、utf-8-sigを指定すると扱いやすくなります。
from pathlib import Path
output = Path("data") / "7203_T.csv"
output.parent.mkdir(parents=True, exist_ok=True)
df.to_csv(output, encoding="utf-8-sig")
print(f"saved: {output.resolve()}")ファイル名にドットを残したくない場合は、ティッカーの.を_へ置換します。
複数銘柄をまとめて取得する
import yfinance as yf
tickers = ["7203.T", "6758.T", "AAPL", "MSFT"]
prices = yf.download(
tickers,
period="6mo",
interval="1d",
group_by="ticker",
auto_adjust=True,
threads=True,
progress=False,
)
for ticker in tickers:
frame = prices[ticker].dropna(how="all")
if not frame.empty:
frame.to_csv(f"data/{ticker.replace('.', '_')}.csv")yfinanceのdownloadは複数銘柄でMultiIndexを返す場合があります。group_byとmulti_level_indexの設定を固定し、ライブラリ更新後に列構造をテストしてください。
既存CSVへ差分更新する
毎日すべての期間を取り直すのではなく、直近データを取得して既存CSVと結合します。重複日は新しく取得した行を残します。
from pathlib import Path
import pandas as pd
import yfinance as yf
def update_daily_csv(ticker: str, csv_path: Path) -> pd.DataFrame:
latest = yf.download(
ticker,
period="10d",
interval="1d",
auto_adjust=True,
progress=False,
multi_level_index=False,
)
if latest.empty:
raise RuntimeError(f"empty dataframe: {ticker}")
latest.index = pd.to_datetime(latest.index)
if csv_path.exists():
current = pd.read_csv(csv_path, index_col=0, parse_dates=True)
combined = pd.concat([current, latest])
else:
combined = latest
combined = combined[~combined.index.duplicated(keep="last")].sort_index()
csv_path.parent.mkdir(parents=True, exist_ok=True)
combined.to_csv(csv_path, encoding="utf-8-sig")
return combined
update_daily_csv("7203.T", Path("data/7203_T.csv"))休場日には新しい行が増えないことがあります。行数が増えなかっただけで障害と判定せず、最終取引日と取得時刻をログへ残します。
分足データを日本時間へ変換する
参考記事にあるUTC時刻への注意は重要です。ただし、常に9時間を加算するより、タイムゾーン情報を確認してAsia/Tokyoへ変換する方が安全です。
import pandas as pd
import yfinance as yf
intraday = yf.download(
"7203.T",
period="5d",
interval="60m",
auto_adjust=True,
progress=False,
multi_level_index=False,
)
index = pd.to_datetime(intraday.index)
if index.tz is None:
index = index.tz_localize("UTC")
intraday.index = index.tz_convert("Asia/Tokyo")
print(intraday.tail())分足は日足より取得可能期間が短く、リアルタイム性や遅延も保証されません。発注判断へ直結させず、取得できる期間と最終時刻を実データで検査してください。
取得後にデータ品質を検査する
HTTP通信が成功しても、欠損や重複を含む場合があります。保存前に最低限の検査を入れます。
def validate_prices(df, ticker: str) -> None:
required = {"Open", "High", "Low", "Close", "Volume"}
missing = required.difference(df.columns)
if missing:
raise ValueError(f"{ticker}: missing columns={sorted(missing)}")
if df.empty:
raise ValueError(f"{ticker}: empty dataframe")
if df.index.has_duplicates:
raise ValueError(f"{ticker}: duplicated dates")
if (df[["Open", "High", "Low", "Close"]] < 0).any().any():
raise ValueError(f"{ticker}: negative price")高値が安値を下回っていないか、最終日が想定取引日から大きく遅れていないかも、用途に応じて確認します。
再試行とログを追加する
ネットワーク障害や一時的な取得失敗を想定し、待ち時間を増やしながら再試行します。
import logging
import time
import yfinance as yf
logging.basicConfig(level=logging.INFO)
def download_with_retry(ticker: str, attempts: int = 3):
for attempt in range(1, attempts + 1):
try:
data = yf.download(
ticker,
period="1mo",
progress=False,
timeout=15,
multi_level_index=False,
)
if not data.empty:
return data
raise RuntimeError("empty dataframe")
except Exception as exc:
logging.warning("attempt=%s ticker=%s error=%s", attempt, ticker, exc)
if attempt == attempts:
raise
time.sleep(2 ** attempt)無制限に再試行すると障害を見逃します。上限回数を決め、最後は終了コードや通知で失敗を検知してください。
よくあるエラーと確認項目
| 症状 | 主な確認項目 |
|---|---|
| 空のDataFrame | ティッカー、上場市場、期間、休場日 |
| 列名が想定と違う | MultiIndex、group_by、ライブラリのバージョン |
| タイムアウト | 回線、取得件数、timeout、再試行間隔 |
| CSVが重複する | 日付インデックスで結合後に重複除去 |
| 日時が9時間ずれる | インデックスのタイムゾーンを確認しtz_convert("Asia/Tokyo") |
| 分足が長期間取れない | intervalごとの取得可能期間を短くして分割取得 |
KeyError: 'Close' | MultiIndex、空データ、auto_adjust、列名を確認 |
| 毎日動かない | 実行パス、仮想環境、作業ディレクトリ、ログ |
無料データと正規APIを使い分ける
| 用途 | 選択の考え方 |
|---|---|
| 学習・個人分析 | 利用条件を確認したうえでyfinanceを検討 |
| 日本株の検証可能な公式データ | J-Quants APIなど正規提供サービスを検討 |
| リアルタイム監視・自動発注 | 契約中の証券会社APIと配信条件を確認 |
| データ再配布・商用提供 | 再配布権を含むデータ契約を確認 |
取得できることと、業務・商用で利用できることは別です。可用性、遅延、訂正値、配当・分割、タイムゾーン、再配布条件を要件として整理してください。
コードを引用・再利用する場合
コードは検証用の最小例です。利用環境でテストし、データ提供元の条件を守ってください。記事や教材で紹介する場合は、次の形式で出典を記載できます。
出典:PyTrade「Python株価取得コード集」(2026年9月14日版)
更新履歴
| 更新日 | 内容 |
|---|---|
| 2026-09-14 | yfinance 1.7.0・pandas 3.0.5・Python 3.12で7203.TとAAPLを各22行保存し、7203.Tの差分更新10行を確認 |
| 2026-09-14 | 競合分析を反映。ライブラリ比較、目的別早見表、差分更新、JST変換、品質検査、正規APIとの使い分けを追加 |
| 2026-09-11 | yfinance 1.7.0・Python 3.12で7203.TとAAPLを取得し、各23行のCSV保存を確認 |
まとめ
株価取得コードは、正常時の数行だけでなく、空データ、タイムアウト、列構造の変化、保存失敗まで想定すると再利用しやすくなります。公開前に固定バージョンで実行テストし、GitHubにも同じコードを置くと引用元としてさらに使いやすくなります。