YouTube動画の文字起こしデータを一括取得&AI要約 - Pythonツール開発記

YouTube動画の文字起こしデータを一括取得&AI要約 - Pythonツール開発記

作成日:
更新日:

最近、AIエージェントでのブラウザ操作や、Playwrightでのテスト自動化など、ログイン処理を伴う自動化の機会が増えてきました。同様に、YouTube動画からの情報収集も自動化できないかと考え、文字起こしを一括取得するツールを開発しました。

なぜこのツールを作ったのか

大量のYouTube動画から目当ての内容の動画を見つけたい、という課題がありました。例えば、特定のチャンネルの過去動画をすべて確認して、自分の知りたいトピックを扱っている動画を効率的に見つけたいケースです。

既存サービスの限界

YouTube動画の文字起こしを取得できるサービスはいくつか存在します。

  • Chrome拡張機能: 1動画ずつ手動で取得する必要がある
  • Webサービス: 無料版では取得数に制限があり、有料版でも大量処理は難しい
  • API課金: 要約文を作成するためには各種AI APIの課金が必要

しかし、数百本の動画を一括で処理し、さらにAIで要約するとなると、既存サービスでは対応が難しいのが現状でした。

開発の動機

  • 情報取得を完全に自動化したい
  • すでに契約済みのCursor(Claude)を使って要約文を作成したい
  • 文字起こしデータをローカルに保存して、いつでも検索・参照できるようにしたい

これらの理由から、自作ツールの開発に踏み切りました。

ツールの概要

主な機能

開発したツール youtube_transcript_tool.py には以下の機能があります。

機能 説明
単一動画の文字起こし取得 URLまたは動画IDを指定して1本の動画を処理
バッチ処理 動画IDリストから複数動画を一括処理
チャンネル全動画取得 チャンネルIDを指定してアップロード動画を全取得
メタ情報取得 YouTube Data API v3で動画タイトル、視聴回数などを取得
IPブロック回避 Cookie、プロキシ、Webshareに対応
Markdown出力 タイムスタンプ付きの見やすい形式で保存

使用ライブラリ

youtube-transcript-api>=0.6.0    # 文字起こし取得
google-api-python-client>=2.0.0  # YouTube Data API(メタ情報取得)
python-dotenv>=1.0.0             # 環境変数管理

youtube-transcript-api の仕組み

文字起こし取得のコアとなる youtube-transcript-api ライブラリの内部処理を解説します。

処理フロー

  1. 動画ページのHTML取得: YouTubeの動画ページにアクセス
  2. Innertube APIキー抽出: HTMLからYouTube内部APIのキーを取得
  3. Innertube APIリクエスト: /youtubei/v1/player エンドポイントにPOSTリクエスト
  4. 字幕情報抽出: レスポンスから利用可能な字幕(手動・自動生成)を取得
  5. 文字起こしデータ取得: 選択した言語の字幕データをフェッチ

対応する字幕タイプ

  • 手動字幕: 動画投稿者が作成した字幕(優先)
  • 自動生成字幕: YouTubeの音声認識による字幕
# 字幕の優先順位で取得
for lang_code in ['ja', 'en']:
    try:
        # まず手動字幕を探す
        transcript = transcript_list.find_manually_created_transcript([lang_code])
        if transcript:
            return transcript
    except NoTranscriptFound:
        pass
    
    # 手動字幕がなければ自動生成字幕
    try:
        transcript = transcript_list.find_generated_transcript([lang_code])
        if transcript:
            return transcript
    except NoTranscriptFound:
        pass

最大の壁: IPブロック問題

問題の発生

開発を進めて実際に大量の動画を処理しようとしたところ、以下のエラーが頻発しました。

YouTube is blocking requests from your IP.

YouTubeは、短時間に大量のリクエストを送信するIPアドレスをブロックする仕組みを持っています。特に以下の条件でブロックされやすいです。

  • クラウドプロバイダーのIP: AWS、GCP、Azureなどのサーバー
  • 短時間での大量リクエスト: 連続して数十〜数百件のリクエスト
  • 同一IPからの継続的なアクセス: 長時間にわたる自動処理

試した対策

1. Cookieファイルの使用

ブラウザでYouTubeにログインした状態のCookieをエクスポートして使用する方法です。

# EditThisCookie拡張機能でエクスポートしたCookieを使用
uv run youtube_transcript_tool.py batch \
  --input-file list.txt \
  --cookies-file cookies.txt

結果: 一時的に改善するが、大量処理には効果が限定的。

2. プロキシの使用

無料のプロキシやVPNを試しましたが、速度が遅く安定しませんでした。

3. Webshareの契約(最終的な解決策)

youtube-transcript-api のREADMEで推奨されている Webshare を契約しました。

Webshareとは: 回転リジデンシャルプロキシを提供するサービス。リクエストごとに異なるIPアドレスを使用できるため、IPブロックを効果的に回避できます。

# Webshare形式のプロキシファイル
# host:port:username:password
p.webshare.io:80:username:password
# プロキシファイルを使用(エラー時は自動で次のプロキシに切り替え)
uv run youtube_transcript_tool.py batch \
  --input-file list.txt \
  --proxies-file config/proxies.txt \
  --request-delay 2.0

結果: 数百本の動画を安定して処理できるようになりました。

実装のポイント

指数バックオフ付きリトライ

レート制限エラーが発生した場合、自動的にリトライする仕組みを実装しました。

def rate_limit_handler(delay=1.0, max_retries=3, backoff_factor=2.0):
    """レート制限対策用デコレータ"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            retries = 0
            current_delay = delay
            
            while retries <= max_retries:
                try:
                    result = func(*args, **kwargs)
                    time.sleep(delay)
                    return result
                except Exception as e:
                    if is_rate_limit_error(e) and retries < max_retries:
                        retries += 1
                        time.sleep(current_delay)
                        current_delay *= backoff_factor  # 1秒 → 2秒 → 4秒
                    else:
                        raise
        return wrapper
    return decorator

Markdown形式での出力

取得した文字起こしは、タイムスタンプ付きのMarkdown形式で保存されます。

# 動画タイトル

## メタ情報

| 項目 | 内容 |
|------|------|
| 動画タイトル | 〇〇の使い方講座 |
| URL | https://www.youtube.com/watch?v=xxxxx |
| チャンネル | 〇〇チャンネル |
| 公開日 | 2025-01-15 |
| 動画時間 | 15分30秒 |
| 視聴回数 | 12,345回 |

## タイムスタンプ付き文字起こし

### 00:00
こんにちは、今日は〇〇について解説します。

### 00:15
まず最初に基本的な概念から説明していきます。

### 00:45
ここで重要なポイントは...

この形式で保存することで、後からCursor AIに読み込ませて要約や質問応答ができます。

Cursor AIでの活用方法

取得した文字起こしデータをCursorで活用する方法を紹介します。

要約の生成

@youtube_transcripts この動画の要点を5つにまとめてください。

特定トピックの検索

@youtube_transcripts 「〇〇」について言及している動画はありますか?

Q&A形式での情報抽出

@youtube_transcripts このチャンネルで推奨されている〇〇の方法は何ですか?

文字起こしデータをローカルに保存しておくことで、Cursorの@ファイル参照機能を使って効率的に情報を検索・要約できます。

使用方法

インストール

# uvを使用
uv pip install -r requirements.txt

# または pip
pip install youtube-transcript-api google-api-python-client python-dotenv

環境変数の設定

YouTube Data API v3のAPIキーが必要です(メタ情報取得時のみ)。

# .envファイルに設定
echo "YOUTUBE_API_KEY=your_api_key_here" > .env

基本的な使い方

# 単一動画の文字起こしを取得
uv run youtube_transcript_tool.py single VIDEO_ID

# 動画IDリストからバッチ処理
uv run youtube_transcript_tool.py batch --input-file list.txt

# チャンネルの全動画を取得(最新50件)
uv run youtube_transcript_tool.py batch \
  --channel-id UCxxxxxxxxxxxx \
  --limit 50

# IPブロック回避(プロキシファイル使用)
uv run youtube_transcript_tool.py batch \
  --input-file list.txt \
  --proxies-file config/proxies.txt \
  --request-delay 2.0 \
  --skip-existing

まとめ

大量のYouTube動画から効率的に情報を抽出するため、文字起こし一括取得ツールを開発しました。

学んだこと

  1. youtube-transcript-api は強力だが、IPブロック対策が必須
  2. Webshare のような回転プロキシサービスを使うことで大量処理が可能に
  3. Markdownで保存することで、Cursor AI との連携が容易

今後の展望

  • 自動要約機能の組み込み(Claude API連携)
  • 動画内容のベクトル検索対応
  • 定期実行による新着動画の自動取得

このツールを使えば、数百本の動画を一晩で文字起こしし、翌朝にはCursorで要約を確認する、というワークフローが実現できます。YouTubeでの情報収集を効率化したい方は、ぜひ参考にしてください。

参考リンク