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]:
|
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 []
|
||||||
|
|||||||
Reference in New Issue
Block a user