「見たいYouTubeチャンネルが多すぎて、時間が足りない」と感じていませんか。
私も情報収集のために多くのチャンネルを登録していますが、毎日すべてを視聴するのは困難でした。
そこで、PythonとGemini APIを使い、お気に入りのチャンネルが更新されたら自動で動画を要約する仕組みを作りました。要約はMarkdownファイルとして出力され、あとから読み返せます。
この仕組みを使えば、(1)新着動画の自動チェック、(2)字幕の自動取得、(3)Gemini APIによる要約生成、(4)Markdownでのメモ保存までを自動化できます。動画の概要を5分ほどで把握でき、視聴時間を大幅に短縮できます。
PARTS LIST /目次
PythonとGemini APIでYouTubeを自動要約してみた
まずは、今回構築するシステムで何ができるのか、どのような技術を使うのかを整理します。
この記事でできること
この記事で紹介するPythonスクリプトを実行すると、以下の4つが自動で可能になります。
自動化ポイント
- 指定したYouTubeチャンネルの最新動画を定期的にチェックします。
- 新しい動画がアップロードされていたら、その動画の字幕データを取得します。
- 取得した字幕と動画情報をGemini APIに送信し、日本語の要約を生成させます。
- 生成された要約を、動画情報と共にMarkdownファイルとして指定フォルダに保存します。
使う技術(Python/Gemini API/YouTube Transcript API)
Gemini APIとは、Googleが提供する生成AIモデル「Gemini」をプログラムから呼び出すためのAPIです。この記事では、このGemini APIを使ってYouTube動画の字幕から日本語の要約文を自動生成します。
今回のシステムは、3つの主要な技術で成り立っています。
- Python: メインとなるプログラミング言語です。各種APIを連携させ、全体の処理を自動化するスクリプトを記述します。
- Gemini API: Googleが提供する最新の生成AIモデルです。今回は、YouTubeの字幕データから高精度な要約を生成するためにGeminiAPIを利用します。なお、Pythonから呼び出す公式ライブラリは旧
google-generativeaiが2025年11月30日でサポート終了し、後継のgoogle-genaiに統合されました。この記事のコードはgoogle-genaiを使用しています。 - YouTube Data API v3: Googleが提供するAPIです。特定チャンネルの動画リストや、動画の詳細情報(タイトル、説明、統計など)を取得するために使います。
- YouTube Transcript API (Pythonライブラリ): YouTube動画の字幕データを簡単に取得できるサードパーティ製のPythonライブラリです。公式APIではありませんが、便利です。なお1.0以降のバージョンでは
get_transcriptが廃止され、YouTubeTranscriptApi().fetch()を使う書き方に変わっています。この記事のコードは後者の書き方で、v1.2.4でfetch()の動作を確認しています。
どんな課題を解決できるのか
この仕組みが解決するのは、ズバリ「情報収集の時短」です。
私自身、見たいyoutubeチャンネルが多すぎることが悩みでした。
有益な情報が詰まった動画でも、1本あたり15分や30分、時には1時間を超えるものもあります。すべてを視聴していては、時間がいくらあっても足りません。
しかし、このシステムを導入してからは、動画がアップロードされたら自動で要約がMarkdownファイルに出力されるようになりました。
メモを読むだけで、動画の主要なポイントを5分ほどで把握できます。
「これは詳しく見るべきだ」と判断した動画だけを、後でじっくり視聴すれば良いため、動画閲覧の時間を劇的に短縮できました。
YouTube要約スクリプトはどんな仕組みで動く?
システムがどのような流れで動作するのか、その仕組みを分解して解説します。全体のプロセスは大きく4つのステップに分かれています。
YouTubeの字幕データを取得する方法
要約の元データとなる「字幕(文字起こしテキスト)」の取得が、このシステムの肝です。
最初に、YouTube Data APIを使い、指定したチャンネルIDから最新の動画リストを取得します。
次に、新しく発見した動画のIDを使い、YouTube Transcript APIにリクエストを送ります。
このライブラリが、動画に付与されている字幕データをテキストとして抽出してくれます。
字幕データが存在しない動画(例: 字幕オフ、音楽のみの動画)の場合、このステップはスキップされ、要約も主にタイトルと説明欄から生成されます。
Gemini APIに要約をリクエストする処理
字幕テキストが取得できたら、いよいよGemini APIの出番です。
取得した「動画タイトル」「動画の説明文」、そして「字幕テキスト」をひとまとめにします。
ひとまとめにした動画情報を、あらかじめ定義したプロンプト(指示文)と一緒にGemini APIに送信します。
プロンプトには「以下の情報を要約してください」「主要ポイントを3点でまとめてください」といった具体的な指示を含めます。
GeminiAPIは、受け取った情報を基に、自然な日本語の要約テキストを生成して返します。
メモ(テキストファイル)への書き出し処理
Gemini APIが生成した要約テキストを、ローカルのファイルとして保存します。
今回のコードでは、読みやすさと管理のしやすさを考慮し、Markdown形式で出力します。
ファイルには、Geminiによる要約内容だけでなく、元の動画タイトル、投稿日、チャンネル名、動画URL、統計情報(再生回数など)も一緒に記録します。
これにより、後からメモを見返したときに、元の動画をすぐに見つけ出せるようになります。
全体のコード構成と実行の流れ
全体の流れは、以下の通りです。
- スクリプトが起動します。
last_checked_videos.json(前回チェックした動画リスト)を読み込みます。youtube_config.json(APIキーやチャンネルID)を読み込みます。- YouTube Data APIで指定チャンネルの最新動画5件を取得します。
- 取得した動画IDと、前回チェックしたIDリストを比較し、新規動画(まだ処理していない動画)を見つけます。
- 新規動画が見つかった場合、1件ずつ処理ループに入ります。
- YouTube Data APIで動画の詳細情報(統計など)を取得します。
- YouTube Transcript APIで字幕を取得します。
- Gemini APIでタイトル、説明、字幕を要約します。
- 要約結果と動画情報をMarkdownファイルとして
summariesフォルダに保存します。 - 全ての新規動画の処理が終わったら、
last_checked_videos.jsonを最新の動画IDリストで上書き保存します。
このスクリプトを定期的に実行することで、チャンネルの更新を自動で追いかけられます。
API利用時の注意点(クォータ・レート制限)
チャンネル数を増やしたり実行頻度を上げたりする前に、2つのAPIが持つ利用上限を把握しておくと、エラーで処理が止まるトラブルを避けやすくなります。
- YouTube Data API v3: Google Cloudプロジェクト単位で既定1日10,000ユニットのクォータがあります。動画一覧の取得(
search.list)は1回あたり1ユニットの消費ですが、search.listには全体の10,000ユニットとは別に1日100回までという専用のクォータ枠が設けられています。そのため無料枠では、他の操作に余裕があってもsearch.listは1日あたり約100回分が実質的な上限です。正確な現在値はGoogle Cloud Consoleの「APIとサービス」→「割り当て」、またはGoogle Cloud公式ドキュメント(クォータの表示と管理)で確認してください。 - Gemini API: 無料枠には1分あたり・1日あたりのリクエスト数上限がありますが、モデルや時期によって変動します。最新の上限値はGemini API公式ドキュメント(レート制限)で確認してください。
チャンネル数が多い場合や実行頻度を上げたい場合は、クォータ超過によるHTTP 403(quotaExceeded)エラーや、Gemini側の429エラーに備えておくと安心です。時間を置くかリトライ処理を追加することを検討してください。
実際に私が3つのチャンネルを対象にこのスクリプトを毎日自動実行し、2026年3月28日から5月30日までの約2か月間のログを集計しました。その結果、新着動画82件のうち60件の要約に成功し、22件(約27%)が失敗していました。失敗の内訳はすべて「503 UNAVAILABLE」というGemini側のモデル混雑によるエラーで、429のクォータ超過エラーは一度も発生していません。
つまり、チャンネル数が少ない個人利用の範囲では、クォータ上限よりもモデル混雑による一時的な503エラーのほうが実際には起こりやすいといえます。数秒〜数十秒の待機を挟んで同じリクエストを再送するだけで、大半は次の試行で成功します。
YouTube自動要約のコード例と解説
お待たせしました。実際に動作するPythonコードを紹介します。
必要なライブラリと事前準備
このスクリプトを実行するには、いくつかの準備が必要です。
1. Pythonライブラリのインストール
以下のライブラリをpipでインストールしてください。
pip install google-api-python-client google-genai youtube-transcript-api
2. APIキーの取得
- YouTube Data API v3 キー: Google Cloud Platform (GCP) コンソールから取得が必要です。「YouTube Data API v3」を有効化し、APIキーを発行します。
- Gemini API キー: Google AI Studio から無料で取得できます。
3. 設定ファイルの作成
スクリプトと同じ階層に、youtube_config.jsonという名前のファイルを作成し、以下の内容を記述します。
YOUR_の部分はご自身の情報に書き換えてください。
{
"youtube_api_key": "YOUR_YOUTUBE_API_KEY",
"gemini_api_key": "YOUR_GEMINI_API_KEY",
"channel_ids": [
"UC_CHANNEL_ID_1",
"UC_CHANNEL_ID_2"
],
"output_folder": "summaries",
"gemini_model": "gemini-2.5-flash"
}
channel_idsには、監視したいYouTubeチャンネルのID(UCから始まる文字列)をリスト形式で複数指定できます。
Pythonコード全文
以下が、YouTubeチャンネルを監視し、新規動画を自動要約するPythonスクリプトの全文です。
import os
import json
import time
import logging
from datetime import datetime, timedelta
from googleapiclient.discovery import build
import google.genai as genai
from youtube_transcript_api import YouTubeTranscriptApi
class YouTubeMonitor:
def __init__(self, config_path='youtube_config.json'):
# 設定ファイルから読み込み
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
self.youtube_api_key = config['youtube_api_key']
self.gemini_api_key = config['gemini_api_key']
if 'channel_ids' in config:
if isinstance(config['channel_ids'][0], dict):
self.channel_ids = [ch['id'] for ch in config['channel_ids']]
else:
self.channel_ids = config['channel_ids']
elif 'channel_id' in config:
self.channel_ids = [config['channel_id']]
else:
raise ValueError("設定ファイルにchannel_idsまたはchannel_idが必要です")
self.gemini_model = config.get('gemini_model', 'gemini-2.5-flash')
# 出力フォルダ設定(デフォルトは'summaries')
self.output_folder = config.get('output_folder', 'summaries')
# YouTube API設定
self.youtube = build('youtube', 'v3', developerKey=self.youtube_api_key)
# Gemini API設定
self.genai_client = genai.Client(api_key=self.gemini_api_key)
# 最後にチェックした動画IDを保存するファイル
self.last_check_file = 'last_checked_videos.json'
# ロギング設定
self.setup_logging()
def setup_logging(self):
"""ロギングの設定"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('youtube_monitor.log', encoding='utf-8'),
logging.StreamHandler()
]
)
logging.info('YouTube監視システムを起動しました')
def get_latest_videos(self, channel_id, max_results=5):
"""特定チャンネルの最新動画を取得"""
try:
request = self.youtube.search().list(
part='snippet',
channelId=channel_id,
maxResults=max_results,
order='date',
type='video'
)
response = request.execute()
logging.info(f"チャンネル {channel_id} から {len(response['items'])} 件の動画を取得しました")
return response['items']
except Exception as e:
logging.error(f"YouTube API エラー (チャンネル: {channel_id}): {e}")
return []
def get_video_details(self, video_id):
"""動画の詳細情報を取得"""
try:
request = self.youtube.videos().list(
part='snippet,statistics',
id=video_id
)
response = request.execute()
if response['items']:
logging.info(f"動画詳細を取得しました: {video_id}")
return response['items'][0]
else:
logging.warning(f"動画詳細が見つかりません: {video_id}")
return None
except Exception as e:
logging.error(f"動画詳細取得エラー: {e}")
return None
def get_video_transcript(self, video_id):
"""動画の字幕を取得"""
try:
transcript = YouTubeTranscriptApi().fetch(video_id, languages=['ja', 'en'])
logging.info(f"字幕を取得しました: {video_id}")
return ' '.join([item.text for item in transcript])
except Exception as e:
logging.warning(f"字幕取得エラー({video_id}): {e}")
return None
def summarize_with_gemini(self, title, description, transcript=None):
"""Geminiを使って動画内容を要約"""
try:
# プロンプト作成
content = f"タイトル: {title}\n\n説明: {description}"
if transcript:
content += f"\n\n字幕内容:\n{transcript[:3000]}" # 字幕は3000文字まで
prompt = f"""
以下のYouTube動画の内容を日本語で要約してください。
要約は以下の形式で出力してください:
## 📹 動画要約
### 🎯 主要ポイント
- [主要な内容を3-5点でまとめる]
### 📝 詳細内容
[動画の詳細な内容説明]
### 🔍 キーワード
[関連するキーワードを3-5個]
---
動画情報:
{content}
"""
response = self.genai_client.models.generate_content(model=self.gemini_model, contents=prompt)
logging.info(f"Geminiで要約を生成しました: {title[:30]}...")
return response.text
except Exception as e:
logging.error(f"Gemini API エラー: {e}")
return None
def load_last_checked_videos(self):
"""最後にチェックした動画IDリストを読み込み"""
try:
if os.path.exists(self.last_check_file):
with open(self.last_check_file, 'r', encoding='utf-8') as f:
return set(json.load(f))
return set()
except Exception as e:
logging.error(f"前回チェックファイル読み込みエラー: {e}")
return set()
def save_last_checked_videos(self, video_ids):
"""チェックした動画IDリストを保存"""
try:
with open(self.last_check_file, 'w', encoding='utf-8') as f:
json.dump(list(video_ids), f, ensure_ascii=False, indent=2)
except Exception as e:
logging.error(f"チェックファイル保存エラー: {e}")
def save_summary_to_markdown(self, video_info, summary):
"""要約をMarkdownファイルに保存"""
try:
# 出力フォルダが存在しない場合は作成
os.makedirs(self.output_folder, exist_ok=True)
# ファイル名を作成(日時 + 動画タイトル)
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
safe_title = "".join(c for c in video_info['title'][:30] if c.isalnum() or c in (' ', '-', '_')).strip()
filename = f"{timestamp}_{safe_title}.md"
filepath = os.path.join(self.output_folder, filename)
# Markdownコンテンツを作成
markdown_content = f"""# {video_info['title']}
**投稿日**: {video_info['published_at']}
**チャンネル**: {video_info['channel_title']}
**動画URL**: https://www.youtube.com/watch?v={video_info['video_id']}
---
{summary}
---
## 📊 統計情報
- 視聴数: {video_info.get('view_count', 'N/A')}
- 高評価数: {video_info.get('like_count', 'N/A')}
- コメント数: {video_info.get('comment_count', 'N/A')}
## 📝 動画説明
{video_info['description'][:500]}{'...' if len(video_info['description']) > 500 else ''}
"""
# ファイルに保存
with open(filepath, 'w', encoding='utf-8') as f:
f.write(markdown_content)
logging.info(f"要約を保存しました: {filepath}")
return filepath
except Exception as e:
logging.error(f"Markdown保存エラー: {e}")
return None
def check_for_new_videos(self):
"""全チャンネルの新規動画をチェックして要約を作成"""
print("新規動画をチェック中...")
last_checked = self.load_last_checked_videos()
all_new_videos = []
all_current_video_ids = set()
# 各チャンネルをチェック
for channel_id in self.channel_ids:
print(f"\nチャンネル {channel_id} をチェック中...")
latest_videos = self.get_latest_videos(channel_id)
for video in latest_videos:
video_id = video['id']['videoId']
all_current_video_ids.add(video_id)
if video_id not in last_checked:
all_new_videos.append(video)
if not all_new_videos:
print("\n新規動画はありませんでした。")
self.save_last_checked_videos(all_current_video_ids)
return
print(f"\n合計 {len(all_new_videos)}件の新規動画を発見しました。")
# 各新規動画を処理
for video in all_new_videos:
video_id = video['id']['videoId']
snippet = video['snippet']
print(f"\n処理中: {snippet['title']}")
video_details = self.get_video_details(video_id)
stats = video_details['statistics'] if video_details else {}
video_info = {
'video_id': video_id,
'title': snippet['title'],
'description': snippet['description'],
'published_at': snippet['publishedAt'],
'channel_title': snippet['channelTitle'],
'view_count': stats.get('viewCount', 'N/A'),
'like_count': stats.get('likeCount', 'N/A'),
'comment_count': stats.get('commentCount', 'N/A')
}
transcript = self.get_video_transcript(video_id)
summary = self.summarize_with_gemini(
video_info['title'],
video_info['description'],
transcript
)
if summary:
self.save_summary_to_markdown(video_info, summary)
else:
print(f"要約の作成に失敗しました: {video_info['title']}")
self.save_last_checked_videos(all_current_video_ids)
print("\n処理完了!")
if __name__ == "__main__":
# 設定ファイルから読み込んで監視システムを初期化
monitor = YouTubeMonitor('youtube_config.json')
monitor.check_for_new_videos()
ポイント解説(エラーハンドリング/APIキー管理)
APIキーの管理 (youtube_config.json)
コード内にAPIキーを直接書き込むのは危険です。
今回のコードでは、youtube_config.jsonという別のファイルにAPIキーを書き出し、その内容をPythonスクリプトが読み込む形にしています。
youtube_config.jsonファイルは、GitHubなどのパブリックな場所に絶対にアップロードしないでください。
YouTube自動要約を実行するとどうなる?
このスクリプトを実際に実行すると、ターミナルと出力フォルダ(summaries)にどのような結果が得られるかを紹介します。
YouTube動画を自動で要約した結果
スクリプトを実行すると、ターミナルには以下のようなログが表示されます。
どのチャンネルをチェックし、どの動画を新規として処理したかがリアルタイムでわかります。
$ python your_script_name.py
2025-11-03 09:40:00,000 - INFO - YouTube監視システムを起動しました
新規動画をチェック中...
チャンネル UC_CHANNEL_ID_1 をチェック中...
2025-11-03 09:40:01,000 - INFO - チャンネル UC_CHANNEL_ID_1 から 5 件の動画を取得しました
チャンネル UC_CHANNEL_ID_2 をチェック中...
2025-11-03 09:40:02,000 - INFO - チャンネル UC_CHANNEL_ID_2 から 5 件の動画を取得しました
合計 1件の新規動画を発見しました。
処理中: 【新機能】Gemini 2.0 が発表されました!
2025-11-03 09:40:03,000 - INFO - 動画詳細を取得しました: video_id_example
2025-11-03 09:40:04,000 - INFO - 字幕を取得しました: video_id_example
2025-11-03 09:40:06,000 - INFO - Geminiで要約を生成しました: 【新機能】Gemini 2.0 が発表されました!...
2025-11-03 09:40:06,100 - INFO - 要約を保存しました: summaries/20251103_094006_新機能Gemini 20 が発表されました.md
処理完了!
生成されたメモファイルの例
summariesフォルダには、以下のようなMarkdownファイル(例: 20251103_094006_新機能Gemini 20 が発表されました.md)が生成されます。
要約と動画情報が一つのファイルにまとまるため、後からの見返しや情報管理が楽になります。
# 【新機能】Gemini 2.0 が発表されました!
**投稿日**: 2025-11-03T09:00:00Z
**チャンネル**: とあるITニュースチャンネル
**動画URL**: https://www.youtube.com/watch?v=video_id_example
---
## 📹 動画要約
### 🎯 主要ポイント
- Googleが新しいAIモデル「Gemini 2.0」を発表しました。
- 従来のモデルと比較し、推論能力と速度が大幅に向上しています。
- 特に日本語の処理精度が改善され、より自然な応答が可能になりました。
### 📝 詳細内容
今回の発表では、Gemini 2.0のアーキテクチャの変更点と、それによるパフォーマンス向上が中心に語られました。開発者向けには新しいAPIエンドポイントが提供され、Flashモデルもアップデートされています。動画では、実際のデモを交えながら新機能が紹介されています。
### 🔍 キーワード
- Gemini 2.0
- Google AI
- 生成AI
- 新機能
---
## 📊 統計情報
- 視聴数: 10500
- 高評価数: 2100
- コメント数: 350
## 📝 動画説明
本日発表されたGoogleの最新AI、Gemini 2.0について速報でお伝えします!
(...以下、動画の説明文が続く)
応用編|Pythonスクリプトを自分好みにカスタマイズする方法
提供したコードはあくまで基本形です。ここから、さらに自分好みにカスタマイズするアイデアを2つ紹介します。
出力形式をMarkdownにする
「生成されたメモファイルの例」で示したとおり、このスクリプトは既に出力形式としてMarkdownを採用しています。
Markdown形式の最大の利点は、Obsidian、Notion、VS Codeなど、多くのメモアプリやエディタでそのまま美しく表示・編集できる点です。
もし、save_summary_to_markdown関数のmarkdown_content変数を編集すれば、出力するMarkdownのフォーマットを自由に変更できます。
例えば、見出しのレベルを変更したり、特定の情報を追加・削除したりするカスタマイズも簡単です。
自動でObsidianに保存する
もしあなたがメモアプリとしてObsidianを使用しているなら、かなり便利です。
ObsidianはローカルのMarkdownファイルを直接管理する(Vaultと呼ばれるフォルダを監視する)仕組みです。
したがって、youtube_config.jsonのoutput_folder設定を、あなたのObsidian Vault内の特定のフォルダ(例: "output_folder": "C:/Users/YourName/Documents/ObsidianVault/YouTubeSummaries")に変更するだけです。
これだけで、Pythonスクリプトが生成した要約メモが、自動的にObsidianのサイドバーに表示されるようになります。
手動でファイルを移動する手間すら不要になり、完全な情報収集の自動化が実現します。
要約対象を絞り込む(キーワードで動画をフィルタする)
登録しているチャンネル数が多いと、新着動画をすべて要約するのはGemini APIの呼び出し回数・保存ファイル数の面で過剰になることがあります。
check_for_new_videosメソッド内では、video_idがlast_checkedにないかを判定しています。ここに、snippet['title']に自分が関心のあるキーワードが含まれているかをチェックする条件を足すだけで、要約対象を絞り込めます。複数キーワードのいずれかに一致したら処理する形にすると、柔軟にフィルタできます。
よくある質問
PythonとGemini APIでYouTube動画を自動要約する仕組みについて、読者からよく聞かれる質問をまとめました。必要なAPIキーの取得先から運用時の注意点まで扱っています。細かい手順や根拠は各見出しの本文もあわせて確認してください。
Q1. Gemini APIでYouTube動画を要約するには何が必要?
A1. YouTube Data APIキーとGemini APIキーの2つが必要です。それぞれGoogle Cloud ConsoleとGoogle AI Studioから無料で取得できます。取得方法は本文の「必要なライブラリと事前準備」で解説しています。
Q2. 字幕がない動画でも要約できる?
A2. 字幕が取得できない動画(字幕オフ・音楽のみの動画など)は字幕取得のステップがスキップされ、動画のタイトルと説明欄をもとに要約が生成されます。字幕ありの場合より要約の精度は落ちます。
Q3. 複数のYouTubeチャンネルを同時に監視できる?
A3. できます。youtube_config.jsonのchannel_idsにチャンネルIDをリスト形式で複数指定するだけで、複数チャンネルを同時に監視できます。
Q4. YouTube Data APIやGemini APIの利用上限(クォータ)はどのくらい?
A4. YouTube Data APIは無料枠で1日あたり約100回分の検索が目安です。Gemini APIは無料枠に1分・1日あたりのリクエスト数上限がありますが、モデルや時期で変動するため、最新の値は各コンソールで確認してください。
Q5. 要約結果はどのように保存される?
A5. Gemini APIが生成した要約と動画情報(タイトル・投稿日・URLなど)をまとめて、Markdown形式のファイルとして指定フォルダに保存します。Obsidianなどのメモアプリでそのまま閲覧できます。
Q6. すべての新着動画を要約すると数が多くなりすぎない?
A6. チャンネル数が多い場合は、動画タイトルに関心のあるキーワードが含まれているかで絞り込む条件を追加すると、要約対象を減らせます。本文の「要約対象を絞り込む」で具体的な方法を解説しています。
Q7. このスクリプトは実際にどのくらい安定して動く?
A7. 私が3チャンネルを対象に2026年3月28日〜5月30日まで毎日自動実行したログでは、新着動画82件のうち60件の要約に成功しました。残り22件はGemini側の一時的な混雑(503エラー)によるもので、クォータ超過が原因で止まったことはありません。
Q8. YouTube Transcript APIのバージョンで書き方は変わる?
A8. はい。1.0以降はget_transcriptが廃止され、YouTubeTranscriptApi().fetch()を使う書き方に変わりました。この記事のコードはv1.2.4でfetch()の動作を確認した書き方です。
まとめ|GeminiとPythonで情報整理を自動化しよう
この記事では、PythonとGemini API、そしてYouTubeのAPIを組み合わせて、特定チャンネルの最新動画を自動で要約するシステムを構築する方法を解説しました。要約結果はMarkdownのメモとして出力されます。
今回のポイントおさらい
今回のシステムのポイントは以下の3点です。
- APIの連携: YouTube Data APIで動画情報を取得し、YouTube Transcript APIで字幕を抽出し、Gemini APIで要約を生成します。これら複数のサービスをPythonが一つの処理として繋ぎました。
- 差分チェック:
last_checked_videos.jsonファイルで処理済みの動画を管理し、新規動画のみを対象とすることで、無駄なAPI呼び出しを防ぎます。 - Markdown出力: 要約結果を汎用性の高いMarkdown形式で保存することで、Obsidianなどのナレッジベースとシームレスに連携できます。
私自身も3つのチャンネルを対象にこのスクリプトを毎日自動実行しています。前述のとおり約2か月間の運用で成功率は約73%、クォータ超過で処理が止まったことは一度もありません。要望があれば、この運用まわりの工夫は別記事にまとめようと思います。
| REV. | DATE | 内容 |
|---|---|---|
| 4 | 2026-10-16 | 図解を描き直し(図面のデザインにそろえた) |
| 3 | 2026-10-14 | 一人称と言い回しの表記をそろえた |
| 2 | 2026-10-08 | 2026年10月時点の情報で全体を見直し(古い記述を1件更新) |
| 1 | 2025-11-09 | 初版 |




