Fix comment fetching: write to temp file instead of parsing stdout

--write-comments writes to .info.json reliably; parsing stdout with
--dump-json was never guaranteed to include comments. Use a TemporaryDirectory,
write the info.json there, read it, then let the context manager clean up.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mattias Tall
2026-05-26 11:38:00 +02:00
parent 18b3c572f1
commit 50ce373767

View File

@@ -386,45 +386,36 @@ def fetch_channel_links(channel_id: str) -> list[str]:
def fetch_video_comments(youtube_video_id: str, max_comments: int = 20) -> list[dict]: def fetch_video_comments(youtube_video_id: str, max_comments: int = 20) -> list[dict]:
"""Fetch top comments via yt-dlp Python API. Returns empty list on failure.""" """Fetch top comments via yt-dlp CLI writing to a temp file. Returns empty list on failure."""
import yt_dlp as _yt_dlp import os
import tempfile
with _cookies_lock: url = f"https://www.youtube.com/watch?v={youtube_video_id}"
cf = _cookies_file
b = _cookies_browser
oauth2 = _use_oauth2
ydl_opts = { with tempfile.TemporaryDirectory() as tmpdir:
"quiet": True, out_tmpl = os.path.join(tmpdir, "%(id)s.%(ext)s")
"no_warnings": True, args = [
"skip_download": True, "yt-dlp", url,
"getcomments": True, "--write-info-json",
"extractor_args": { "--write-comments",
"youtube": { "--extractor-args", f"youtube:max_comments={max_comments};comment_sort=top",
"max_comments": [str(max_comments), str(max_comments)], "--no-download",
"comment_sort": ["top"], "--no-playlist",
} "--quiet",
}, "--output", out_tmpl,
} *_cookie_args(),
if oauth2: ]
ydl_opts["username"] = "oauth2" _run(args, timeout=90)
ydl_opts["password"] = ""
elif cf and Path(cf).exists(): info = None
ydl_opts["cookiefile"] = cf for fname in os.listdir(tmpdir):
else: if fname.endswith(".info.json"):
for candidate in _AUTO_COOKIES_PATHS: try:
if Path(candidate).exists(): with open(os.path.join(tmpdir, fname)) as f:
ydl_opts["cookiefile"] = candidate info = json.load(f)
except Exception:
pass
break break
else:
if b and not cf:
ydl_opts["cookiesfrombrowser"] = (b,)
try:
with _yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(f"https://www.youtube.com/watch?v={youtube_video_id}", download=False)
except Exception:
return []
if not info: if not info:
return [] return []