You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:35:56