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