この記事では、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 Data API v3とは別のライブラリです。動画タイトル、再生数、チャンネル情報などのメタデータを安定して取得したい場合は、公式のYouTube Data APIを使うほうが向いています。
インストール
まず、Python環境にライブラリをインストールします。
pip install youtube-transcript-api仮想環境を使っている場合は、仮想環境を有効化した状態で実行してください。
動画IDを用意する
ライブラリに渡すのは、動画URL全体ではなく動画IDです。たとえば次のURLであれば、動画IDは dQw4w9WgXcQ の部分です。
https://www.youtube.com/watch?v=dQw4w9WgXcQURLから動画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_generated が True の場合は、自動生成字幕です。自動生成字幕は便利ですが、固有名詞や専門用語、ゲーム名、アプリ名が崩れることがあります。
手動字幕と自動生成字幕の使い分け
| 種類 | 特徴 | 分析時の注意 |
|---|---|---|
| 手動字幕 | 投稿者や制作者が用意した字幕 | 比較的読みやすいが、完全な文字起こしとは限らない |
| 自動生成字幕 | YouTubeが音声から生成した字幕 | 誤認識が含まれやすいため、固有名詞や数字は確認する |
| 翻訳字幕 | 元字幕を別言語へ翻訳した字幕 | 分析する言語やニュアンスが変わる可能性がある |
分析目的であれば、手動字幕がある場合は手動字幕を優先し、自動生成字幕を使う場合は誤認識がある前提で扱うのがよいです。
取得できないときの主な理由
- 動画に字幕が付いていない
- 指定した言語の字幕が存在しない
- 年齢制限や地域制限などでアクセスできない
- YouTube側の仕様変更によりライブラリが一時的に動かない
- 短時間に多くのリクエストを送り、アクセスが制限されている
特に公開サービスやクラウド環境から大量に実行する場合、ブロックや制限に遭遇しやすくなります。必要な動画だけを対象にし、取得できない場合は無理に回避策へ寄せすぎないほうが運用しやすいです。
他の方法との使い分け
| 方法 | 向いている用途 | 注意点 |
|---|---|---|
| YouTube Data API | 動画タイトル、チャンネル、再生数などのメタデータ取得 | 字幕本文の取得には向かない |
| youtube-transcript-api | 字幕が付いている動画の字幕取得 | 非公式ライブラリなので仕様変更の影響を受ける |
| yt-dlp | 許諾済み素材の字幕・音声取得や前処理 | 利用範囲とサービス規約の確認が必要 |
| Whisper | 字幕がない許諾済み音声の文字起こし | 音声取得と文字起こし精度の確認が必要 |
字幕が用意されている動画なら youtube-transcript-api は軽く試せます。字幕がない許諾済み素材を扱う場合は、Whisperで文字起こしする流れを検討します。
分析に使うときの書き方
字幕データを記事に使う場合、字幕本文を長く引用するより、次のように処理内容と読み取り結果を分けて書くと自然です。
- 取得対象は許諾済み動画であること
- 字幕の種類が手動字幕か自動生成字幕か
- 分析前にどのような整形をしたか
- 頻出語、話題、時間帯ごとの変化など、集計結果として読める範囲
- 誤認識や字幕欠落の可能性
このあたりを明記しておくと、取得結果をそのまま正解として扱っていないことが読者にも伝わります。
関連記事
- YouTubeの情報を取得する方法まとめ|公式API・字幕・チャット・文字起こしの使い分け
- YouTube Data API v3入門|APIキー発行からPythonで動画情報を取得するまで
- yt-dlpで許諾済み動画の音声・字幕を分析用に取得する方法|Whisper文字起こし前処理
- Whisperで許諾済み音声を文字起こしして要約する方法|Pythonで分析前処理を整える
まとめ
youtube-transcript-api を使うと、字幕が用意されているYouTube動画から字幕データを取得できます。動画IDを指定し、言語を選び、CSVやテキストに保存しておくと、要約やキーワード抽出などの前処理に使いやすくなります。
一方で、公式APIではないこと、字幕本文はコンテンツそのものに近いこと、自動生成字幕には誤認識があることには注意が必要です。公開記事では全文転載ではなく、取得条件と限界を明記したうえで、傾向や話題の整理として活用するのがよいと思います。