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

如何将yt-dlp终端输出转为字典后生成Pandas DataFrame?

解决yt-dlp格式列表转Pandas DataFrame的问题

问题说明

想要通过URL获取视频格式列表,将yt-dlp的终端输出转为字典后生成Pandas DataFrame,但直接按行分割的方式未得到预期结果。

原尝试代码:

import subprocess
import pandas as pd


url = 'https://www.youtube.com/watch?v=kjYW63CVbsE'

command = subprocess.getoutput('yt-dlp --list-formats "{url}"'.format(url=url))
output_lines = command.split('\n')
headers = output_lines[6].split()
format_list = []
for line in output_lines[::]:
    values = line.split()
    format_info = {}
    for i in range(len(headers)):
        format_info[headers[i]] = values[i]
    format_list.append(format_info)

df = pd.DataFrame(format_list)

print(df)

原代码的问题

  1. 字段拆分错误:直接用split()会把带空格的字段(比如1080p 60fps)拆成多个元素,导致与表头的键值对应关系混乱。
  2. 未过滤无效行:yt-dlp输出包含开头说明文本、空行、分隔线等无格式数据的行,直接遍历所有行会引发键值不匹配甚至报错。
  3. 表头索引不可靠:依赖固定索引output_lines[6]获取表头,不同环境或yt-dlp版本的输出行数可能变化,导致表头获取错误。

更可靠的两种解决方案

方案一:用yt-dlp的JSON输出直接解析(推荐)

yt-dlp支持直接输出JSON格式的结构化数据,无需手动解析终端文本,这是最稳定的方式:

import subprocess
import json
import pandas as pd

url = 'https://www.youtube.com/watch?v=kjYW63CVbsE'

# 调用yt-dlp,输出JSON格式的格式列表
result = subprocess.run(
    ['yt-dlp', '--list-formats', '--dump-json', url],
    capture_output=True,
    text=True,
    check=True
)

# 解析每行JSON数据,得到格式条目列表
format_data = [json.loads(line) for line in result.stdout.strip().split('\n')]

# 生成Pandas DataFrame
df = pd.DataFrame(format_data)
print(df)

说明:--dump-json参数让yt-dlp输出每个格式的JSON对象,每行一个,直接解析即可得到完整结构化数据,字段比终端输出更丰富。

方案二:改进终端输出的解析(适合必须用终端文本的场景)

如果一定要解析终端输出文本,需处理字段空格问题并过滤无效行:

import subprocess
import pandas as pd
import re

url = 'https://www.youtube.com/watch?v=kjYW63CVbsE'

command_output = subprocess.getoutput('yt-dlp --list-formats "{url}"'.format(url=url))
# 过滤空行并去除每行首尾空格
output_lines = [line.strip() for line in command_output.split('\n') if line.strip()]

# 定位表头行(匹配包含"ID"和"RESOLUTION"的行)
header_line = None
for line in output_lines:
    if line.startswith('ID') and 'RESOLUTION' in line:
        header_line = line
        break

if not header_line:
    raise ValueError("未找到格式列表表头")

# 处理复合表头(比如"FRAME RATE"合并为"FRAME_RATE")
headers = []
parts = header_line.split()
i = 0
while i < len(parts):
    if parts[i] == 'FRAME' and i+1 < len(parts) and parts[i+1] == 'RATE':
        headers.append('FRAME_RATE')
        i += 2
    else:
        headers.append(parts[i])
        i += 1

# 跳过表头和分隔线,定位数据行起始位置
start_idx = output_lines.index(header_line) + 2
format_list = []

# 用正则匹配格式行,避免空格拆分问题
pattern = r'^(\d+)\s+(\w+)\s+(\S+\s*\S*)\s+(\d+\.?\d*)?\s+(\S+)\s+(\S+)\s*(.*)$'
for line in output_lines[start_idx:]:
    match = re.match(pattern, line)
    if match:
        values = [v if v else None for v in match.groups()]
        format_info = dict(zip(headers[:len(values)], values))
        format_list.append(format_info)

df = pd.DataFrame(format_list)
print(df)

说明:通过正则表达式匹配对齐的终端输出行,能有效处理带空格的字段,同时过滤无效数据行。

内容的提问来源于stack exchange,提问作者Gordon Chao

相关产品推荐
方舟 Agent Plan

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

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