選ぶ知識を、あなたの力に。
当サイトはプロモーションを含みます
記事一覧へPython

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

公開 2026.09.14 約10分
Pythonで株価データを取得してCSVへ保存するコード集

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で統一します。

横にスクロールできます →
比較項目yfinanceyahoo_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 pandas

macOS・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.txt

1銘柄の日足を取得する

日本株は、一般に証券コードの後ろへ.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_bymulti_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-14yfinance 1.7.0・pandas 3.0.5・Python 3.12で7203.TとAAPLを各22行保存し、7203.Tの差分更新10行を確認
2026-09-14競合分析を反映。ライブラリ比較、目的別早見表、差分更新、JST変換、品質検査、正規APIとの使い分けを追加
2026-09-11yfinance 1.7.0・Python 3.12で7203.TとAAPLを取得し、各23行のCSV保存を確認

まとめ

株価取得コードは、正常時の数行だけでなく、空データ、タイムアウト、列構造の変化、保存失敗まで想定すると再利用しやすくなります。公開前に固定バージョンで実行テストし、GitHubにも同じコードを置くと引用元としてさらに使いやすくなります。

本記事は情報提供を目的としたもので、契約・投資判断はご自身の責任で行ってください。