yt-dlp驱动的Telegram机器人部分YouTube搜索无结果问题排查
问题概述
在MacOS上开发Telegram机器人,通过yt-dlp实现功能:接收视频链接或名称后,返回YouTube前10条搜索结果供用户选择下载。多数查询可正常返回结果,但搜索「Stxrbxtn」时机器人提示无结果——实际YouTube存在大量相关视频,且返回的search_results显示_type: 'playlist'、entries: []。已尝试设置yes-playlist: False,但问题依旧。
相关代码
@bot.message_handler(func=lambda message: is_started is True) def handle_message(message): global user_format_choice global video_links global user_video_url query = message.text print("ISmessage_handler_func") if AddFunc.is_valid_url(query): print("message_handler_url_accepted") user_video_url = query kb = types.InlineKeyboardMarkup(row_width=1) btn_audio = types.InlineKeyboardButton(text='Скачать аудио', callback_data='audio') btn_video = types.InlineKeyboardButton(text='Скачать видео', callback_data='video') kb.add(btn_audio, btn_video) bot.send_message(message.chat.id, "Выберите действие:", reply_markup=kb) else: video_links.clear() print("message_handler_url_is_not_accepted") print(query) ydl_opts = { 'quiet': True, 'yes-playlist': False, 'max_downloads' : 10, 'skip_download' : True } print(1) with yt_dlp.YoutubeDL(ydl_opts) as ydl: search_results = ydl.extract_info(f"ytsearch{numberOfVideos}:{query}", download=False) print(2) print(search_results) for entry in search_results['entries']: print("1 time loop got") video_title = entry['title'] video_link = entry['url'] video_links.append((video_title, video_link)) print(3) keyboard = types.InlineKeyboardMarkup(row_width=1) for i, (video_title, video_link) in enumerate(video_links[:numberOfVideos]): button_text = f"{i + 1}. {video_title}" button = types.InlineKeyboardButton(text=button_text, callback_data=video_link) keyboard.add(button) print(4) if video_links.__len__() != 0: bot.send_message(message.chat.id, f"Вот {video_links.__len__()} видео по вашему запросу:", reply_markup=keyboard) else: bot.send_message(message.chat.id, f"По вашему запросу ничего не найдено! :(", reply_markup=keyboard)
错误输出
搜索「Stxrbxtn」时返回的search_results:
{'id': 'Stxrbxtn', 'title': 'Stxrbxtn', '_type': 'playlist', 'entries': [], 'webpage_url': 'ytsearch10:Stxrbxtn', 'original_url': 'ytsearch10:Stxrbxtn', 'webpage_url_basename': 'Stxrbxtn', 'webpage_url_domain': None, 'extractor': 'youtube:search', 'extractor_key': 'YoutubeSearch', 'playlist_count': 0, 'epoch': 1698245758}
解决办法
1. 强制指定搜索视频类型
yt-dlp默认会模糊匹配内容类型,当关键词与某个空playlist名称完全匹配时,会优先返回该空playlist。可以在搜索query后添加filter:video,强制YouTube只返回视频结果:
search_results = ydl.extract_info(f"ytsearch{numberOfVideos}:{query} filter:video", download=False)
2. 调整ydl_opts配置
在ydl_opts中添加'extract_flat': True,强制yt-dlp直接提取搜索结果的原始条目,跳过playlist解析步骤:
ydl_opts = { 'quiet': True, 'yes-playlist': False, 'max_downloads': 10, 'skip_download': True, 'extract_flat': True # 新增配置 }
3. 更新yt-dlp到最新版本
旧版本yt-dlp可能存在搜索解析的bug,执行以下命令更新:
pip install --upgrade yt-dlp
4. 增加兜底判断逻辑
在处理搜索结果前先判断类型,如果是空playlist,则重新发起带视频过滤的搜索:
with yt_dlp.YoutubeDL(ydl_opts) as ydl: search_results = ydl.extract_info(f"ytsearch{numberOfVideos}:{query}", download=False) # 新增判断:若为空playlist,重新搜索视频 if search_results.get('_type') == 'playlist' and not search_results.get('entries'): search_results = ydl.extract_info(f"ytsearch{numberOfVideos}:{query} filter:video", download=False) # 后续遍历条目逻辑不变
内容的提问来源于stack exchange,提问作者Bawich
相关产品推荐
相关产品推荐

