如何用yt-dlp Python代码跳过播放列表中的私有视频?
问题描述
用yt-dlp库编写Python脚本下载YouTube播放列表时,遇到无访问权限的私有视频会触发报错,导致流程中断。已尝试配置rejecttitle、ignore-errors等选项,也查阅了yt-dlp的YoutubeDL.py文档,但问题仍未解决,寻求跳过这类私有视频的可行方案。
代码
from __future__ import unicode_literals from datetime import datetime import os import shutil import sys import time import traceback from os import system, name import yt_dlp as yb with open("location.txt", 'w+t') as s: s.write(input("请输入保存文件的路径: ")) s.seek(0) data = s.read() print("缩略图将被移动到 " + data + "\thumbnail") def run(): while True: video_url = input("\n请输入YouTube视频/播放列表链接: ") video_info = yb.YoutubeDL().extract_info( url=video_url, download=False) filename = f"{video_info['title']}" ydl_opts = { 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best', 'download_archive': 'downloaded_songs.txt', 'windowsfilenames': True, 'outtmpl': data + '/%(title)s.%(ext)s', 'writesubtitles': True, 'subtitleslangs': ['en', '-live_chat'], 'writethumbnail': True, 'embedthumbnail': True, 'abort_on_unavailable_fragments': False, 'ignoreerrors': True, 'verbose': True, 'postprocessors': [ {'key': 'FFmpegMetadata', 'add_metadata': True, }, {'key': 'FFmpegEmbedSubtitle'}, {'key': 'EmbedThumbnail', 'already_have_thumbnail': True, }, ] } with yb.YoutubeDL(ydl_opts) as ydl: ydl.download([video_info['webpage_url']]) print("\n下载完成... {}".format(filename)) thumbnail_path() clear() def thumbnail_path(): start_time = datetime.now() sourcepath = data sourcefiles = os.listdir(sourcepath) destinationpath = data + '/thumbnail' if not os.path.exists(destinationpath): os.makedirs(destinationpath) for file in sourcefiles: if file.endswith('.webp'): shutil.move(os.path.join(sourcepath, file), os.path.join(destinationpath, file)) end_time = datetime.now() print('处理时长: {}'.format(end_time - start_time)) def close(): print('\n再见') time.sleep(1) sys.exit() def clear(): while True: ans = input("\n是否继续下载? (y/n) ") if ans.lower() == "y": system('cls' if name == "nt" else 'clear') run() elif ans.lower() == 'n': system('cls' if name == "nt" else 'clear') close() else: print("请输入'y'或'n'\n") if __name__ == '__main__': try: run() except KeyboardInterrupt: print('\n操作被中断') clear() except Exception: with open("log.txt", "w") as log: traceback.print_exc(file=log) print('\n错误信息已写入log.txt') close()
报错信息
ERROR: [youtube] FvnQJZnnXXo: 私有视频。如果已获得访问权限,请登录账号
log.txt输出
Traceback (most recent call last): File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\extractor\common.py", line 640, in extract ie_result = self._real_extract(url) File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\extractor\youtube.py", line 3477, in _real_extract self.raise_no_formats(reason, expected=True) File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\extractor\common.py", line 1124, in raise_no_formats raise ExtractorError(msg, expected=expected, video_id=video_id) yt_dlp.utils.ExtractorError: 私有视频。如果已获得访问权限,请登录账号 During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\YoutubeDL.py", line 1420, in wrapper return func(self, *args, **kwargs) File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\YoutubeDL.py", line 1490, in __extract_info ie_result = ie.extract(url) File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\extractor\common.py", line 666, in extract raise type(e)(e.orig_msg, **kwargs) yt_dlp.utils.ExtractorError: [youtube] FvnQJZnnXXo: 私有视频。如果已获得访问权限,请登录账号 During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\User\PycharmProjects\YouTube-\YouMain.py", line 105, in <module> run() File "C:\Users\User\PycharmProjects\YouTube-\YouMain.py", line 23, in run video_info = yb.YoutubeDL().extract_info( File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\YoutubeDL.py", line 1411, in extract_info return self.__extract_info(url, self.get_info_extractor(ie_key), download, extra_info, process) File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\YoutubeDL.py", line 1438, in wrapper self.report_error(str(e), e.format_traceback()) File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\YoutubeDL.py", line 962, in report_error self.trouble(f'{self._format_err("ERROR:", self.Styles.ERROR)} {message}', *args, **kwargs) File "C:\Users\User\PycharmProjects\YouTube-\venv\lib\site-packages\yt_dlp\YoutubeDL.py", line 905, in trouble raise DownloadError(message, exc_info) yt_dlp.utils.DownloadError: ERROR: [youtube] FvnQJZnnXXo: 私有视频。如果已获得访问权限,请登录账号
解决方案
问题核心在于:你调用extract_info时使用的是默认YoutubeDL()实例,该实例未配置ignoreerrors=True,导致提取私有视频信息时直接抛出异常,后续的下载环节根本没机会触发错误跳过逻辑。
修改方案如下:
- 先定义完整的
ydl_opts配置,再基于该配置创建YoutubeDL实例,统一用这个实例处理信息提取和下载 - 直接传入播放列表URL让yt-dlp自动遍历处理,无需手动拆分视频链接
修改后的核心代码片段:
def run(): while True: video_url = input("\n请输入YouTube视频/播放列表链接: ") ydl_opts = { 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best', 'download_archive': 'downloaded_songs.txt', 'windowsfilenames': True, 'outtmpl': data + '/%(title)s.%(ext)s', 'writesubtitles': True, 'subtitleslangs': ['en', '-live_chat'], 'writethumbnail': True, 'embedthumbnail': True, 'abort_on_unavailable_fragments': False, 'ignoreerrors': True, # 关键配置,必须在实例化时传入 'verbose': True, 'postprocessors': [ {'key': 'FFmpegMetadata', 'add_metadata': True}, {'key': 'FFmpegEmbedSubtitle'}, {'key': 'EmbedThumbnail', 'already_have_thumbnail': True}, ] } with yb.YoutubeDL(ydl_opts) as ydl: # 用同一个实例处理信息提取和下载,download=True直接触发下载 video_info = ydl.extract_info(url=video_url, download=True) # 区分单个视频和播放列表的情况 if 'entries' in video_info: # 播放列表:遍历所有成功下载的条目 for entry in video_info['entries']: if entry: print("\n下载完成... {}".format(entry['title'])) else: # 单个视频:直接输出标题 print("\n下载完成... {}".format(video_info['title'])) thumbnail_path() clear()
额外说明:
ignoreerrors=True的作用是让yt-dlp遇到错误时跳过当前条目、继续处理后续内容,必须在创建YoutubeDL实例时传入才会生效- 原代码中先调用无配置的
extract_info,这一步就会因私有视频报错中断,后续的下载配置完全没发挥作用 - 直接传入播放列表URL时,yt-dlp会自动遍历所有视频,错误条目会被自动跳过,无需手动处理
内容的提问来源于stack exchange,提问作者mitchell bakx
相关产品推荐
相关产品推荐

