YouTubeデータ取得 データ取得

youtube-transcript-apiで許諾済み動画の字幕を取得する方法|Pythonで分析前処理を整える

2025年9月29日

この記事では、Pythonライブラリ youtube-transcript-api を使って、YouTube動画の字幕データを取得し、分析しやすい形に保存する方法をまとめます。

対象は、自分の動画、利用許諾のある動画、または権利関係を確認できる素材です。字幕本文は動画の内容そのものに近いため、取得したテキストをそのまま公開するのではなく、要約、分類、キーワード抽出などの分析前処理として扱う前提で進めます。

この記事でできること

  • youtube-transcript-api で字幕を取得する
  • 取得できる字幕の言語や種類を確認する
  • 字幕をCSVやテキストに保存する
  • 手動字幕と自動生成字幕の違いを意識して扱う
  • YouTube Data API、yt-dlp、Whisperとの使い分けを整理する

利用上の注意

youtube-transcript-api は、YouTube Data APIの公式機能ではありません。APIキーなしで字幕を取得できる便利なライブラリですが、YouTube側の仕様変更や制限の影響を受ける可能性があります。

  • 自分の動画、許諾済み動画、または権利関係を確認できる動画を対象にしてください。
  • 字幕全文をそのまま記事に転載する使い方は避けてください。
  • 取得できる字幕がない動画もあります。
  • 自動生成字幕には誤認識が含まれるため、重要な判断には元動画の確認が必要です。
  • 大量取得や短時間の連続アクセスは避け、必要な範囲に絞って実行してください。

このサイトでは、字幕データは「動画内容を分析するための中間データ」として扱います。公開記事に使う場合は、全文引用ではなく、話題の分類や傾向の整理に寄せる方針です。

youtube-transcript-apiとは

youtube-transcript-api は、YouTube動画に付いている字幕・文字起こしデータをPythonから取得するためのライブラリです。公式READMEでは、手動字幕、自動生成字幕、翻訳字幕の取得に対応していることが説明されています。

youtube-transcript-api GitHub

ただし、これはYouTube Data API v3とは別のライブラリです。動画タイトル、再生数、チャンネル情報などのメタデータを安定して取得したい場合は、公式のYouTube Data APIを使うほうが向いています。

インストール

まず、Python環境にライブラリをインストールします。

pip install youtube-transcript-api

仮想環境を使っている場合は、仮想環境を有効化した状態で実行してください。

動画IDを用意する

ライブラリに渡すのは、動画URL全体ではなく動画IDです。たとえば次のURLであれば、動画IDは dQw4w9WgXcQ の部分です。

https://www.youtube.com/watch?v=dQw4w9WgXcQ

URLから動画IDを取り出す簡単な関数を用意しておくと便利です。

from urllib.parse import parse_qs, urlparse


def extract_video_id(url_or_id: str) -> str:
    if "youtube.com" not in url_or_id and "youtu.be" not in url_or_id:
        return url_or_id

    parsed = urlparse(url_or_id)

    if parsed.netloc.endswith("youtu.be"):
        return parsed.path.lstrip("/")

    query = parse_qs(parsed.query)
    return query["v"][0]

字幕を取得する基本コード

現在のREADMEでは、YouTubeTranscriptApi() のインスタンスを作って fetch() を呼び出す例が案内されています。

from youtube_transcript_api import YouTubeTranscriptApi

video_id = "dQw4w9WgXcQ"

ytt_api = YouTubeTranscriptApi()
transcript = ytt_api.fetch(video_id, languages=["ja", "en"])

for snippet in transcript:
    print(snippet.start, snippet.duration, snippet.text)

languages=["ja", "en"] は、まず日本語字幕を探し、なければ英語字幕を探す指定です。対象動画に字幕がない場合や、指定した言語の字幕がない場合は取得できません。

CSVに保存する

分析前処理として使うなら、開始秒、継続時間、本文をCSVに保存しておくと扱いやすいです。

import csv
from pathlib import Path

from youtube_transcript_api import YouTubeTranscriptApi

video_id = "dQw4w9WgXcQ"
output_dir = Path("outputs/subtitles")
output_dir.mkdir(parents=True, exist_ok=True)

ytt_api = YouTubeTranscriptApi()
transcript = ytt_api.fetch(video_id, languages=["ja", "en"])

csv_path = output_dir / f"{video_id}_subtitles.csv"

with csv_path.open("w", encoding="utf-8-sig", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["start", "duration", "text"])
    writer.writeheader()

    for item in transcript:
        writer.writerow({
            "start": round(item.start, 2),
            "duration": round(item.duration, 2),
            "text": item.text,
        })

print(f"saved: {csv_path}")

CSVにしておくと、Google Sheetsやpandasで確認しやすくなります。字幕本文を公開するためではなく、後続の分類や要約に使う中間データとして保存します。

テキストとして保存する

要約やキーワード抽出に使うだけなら、字幕をつなげたテキストファイルも用意しておくと便利です。

from pathlib import Path

from youtube_transcript_api import YouTubeTranscriptApi

video_id = "dQw4w9WgXcQ"
output_dir = Path("outputs/subtitles")
output_dir.mkdir(parents=True, exist_ok=True)

ytt_api = YouTubeTranscriptApi()
transcript = ytt_api.fetch(video_id, languages=["ja", "en"])

text = "\n".join(item.text for item in transcript)

txt_path = output_dir / f"{video_id}_subtitles.txt"
txt_path.write_text(text, encoding="utf-8")

print(f"saved: {txt_path}")

後から公開記事に使う場合は、全文をそのまま載せるのではなく、話題の傾向や要点を自分の言葉で整理します。

利用可能な字幕を確認する

動画によって、手動字幕、自動生成字幕、翻訳可能な字幕の有無が異なります。先に利用可能な字幕を確認すると、取得できない理由を切り分けやすくなります。

from youtube_transcript_api import YouTubeTranscriptApi

video_id = "dQw4w9WgXcQ"

ytt_api = YouTubeTranscriptApi()
transcript_list = ytt_api.list(video_id)

for transcript in transcript_list:
    print({
        "language": transcript.language,
        "language_code": transcript.language_code,
        "is_generated": transcript.is_generated,
        "is_translatable": transcript.is_translatable,
    })

is_generatedTrue の場合は、自動生成字幕です。自動生成字幕は便利ですが、固有名詞や専門用語、ゲーム名、アプリ名が崩れることがあります。

手動字幕と自動生成字幕の使い分け

種類特徴分析時の注意
手動字幕投稿者や制作者が用意した字幕比較的読みやすいが、完全な文字起こしとは限らない
自動生成字幕YouTubeが音声から生成した字幕誤認識が含まれやすいため、固有名詞や数字は確認する
翻訳字幕元字幕を別言語へ翻訳した字幕分析する言語やニュアンスが変わる可能性がある

分析目的であれば、手動字幕がある場合は手動字幕を優先し、自動生成字幕を使う場合は誤認識がある前提で扱うのがよいです。

取得できないときの主な理由

  • 動画に字幕が付いていない
  • 指定した言語の字幕が存在しない
  • 年齢制限や地域制限などでアクセスできない
  • YouTube側の仕様変更によりライブラリが一時的に動かない
  • 短時間に多くのリクエストを送り、アクセスが制限されている

特に公開サービスやクラウド環境から大量に実行する場合、ブロックや制限に遭遇しやすくなります。必要な動画だけを対象にし、取得できない場合は無理に回避策へ寄せすぎないほうが運用しやすいです。

他の方法との使い分け

方法向いている用途注意点
YouTube Data API動画タイトル、チャンネル、再生数などのメタデータ取得字幕本文の取得には向かない
youtube-transcript-api字幕が付いている動画の字幕取得非公式ライブラリなので仕様変更の影響を受ける
yt-dlp許諾済み素材の字幕・音声取得や前処理利用範囲とサービス規約の確認が必要
Whisper字幕がない許諾済み音声の文字起こし音声取得と文字起こし精度の確認が必要

字幕が用意されている動画なら youtube-transcript-api は軽く試せます。字幕がない許諾済み素材を扱う場合は、Whisperで文字起こしする流れを検討します。

分析に使うときの書き方

字幕データを記事に使う場合、字幕本文を長く引用するより、次のように処理内容と読み取り結果を分けて書くと自然です。

  • 取得対象は許諾済み動画であること
  • 字幕の種類が手動字幕か自動生成字幕か
  • 分析前にどのような整形をしたか
  • 頻出語、話題、時間帯ごとの変化など、集計結果として読める範囲
  • 誤認識や字幕欠落の可能性

このあたりを明記しておくと、取得結果をそのまま正解として扱っていないことが読者にも伝わります。

関連記事

まとめ

youtube-transcript-api を使うと、字幕が用意されているYouTube動画から字幕データを取得できます。動画IDを指定し、言語を選び、CSVやテキストに保存しておくと、要約やキーワード抽出などの前処理に使いやすくなります。

一方で、公式APIではないこと、字幕本文はコンテンツそのものに近いこと、自動生成字幕には誤認識があることには注意が必要です。公開記事では全文転載ではなく、取得条件と限界を明記したうえで、傾向や話題の整理として活用するのがよいと思います。

-YouTubeデータ取得, データ取得