使用pytube转换YouTube字幕为srt格式时报KeyError:'start'的问题
报错原因
- 该问题是pytube内置的
xml_caption_to_srt方法的兼容性缺陷导致:YouTube近年更新了字幕XML的返回结构,部分字幕节点<p>没有直接携带start属性,或者存在无属性的空占位节点,方法未做异常校验直接强制读取start属性就会触发KeyError。 - 你代码中调用的
a.en是YouTube自动生成的英文字幕,结构和人工上传字幕差异更大,更容易触发该问题。
解决方法
以下提供两个可直接落地的方案,优先选择第一种,无需修改依赖源码:
方案1:手动解析XML字幕转换为SRT格式
直接读取xml_captions内容,自行做节点校验和格式转换,完整代码如下:
from pytube import YouTube import xml.etree.ElementTree as ET import math def xml_to_srt(xml_content): root = ET.fromstring(xml_content) srt_lines = [] count = 1 # 遍历字幕节点,跳过无有效属性的无效节点 for p in root.findall('.//p'): if 'start' not in p.attrib or 'd' not in p.attrib: continue # 转换秒级时间为SRT标准格式 00:00:00,000 start = float(p.attrib['start']) duration = float(p.attrib['d']) end = start + duration def format_time(sec): hours = math.floor(sec / 3600) mins = math.floor((sec % 3600) / 60) secs = sec % 60 return f"{hours:02d}:{mins:02d}:{secs:06.3f}".replace('.', ',') # 提取字幕文本,兼容自动字幕的嵌套标签结构 text = ''.join([s.text for s in p.findall('.//s') if s.text]) if p.findall('.//s') else p.text if not text: continue # 拼接SRT标准块 srt_lines.append(f"{count}") srt_lines.append(f"{format_time(start)} --> {format_time(end)}") srt_lines.append(text.strip()) srt_lines.append('') count += 1 return '\n'.join(srt_lines) # 原有业务逻辑 video=YouTube('https://www.youtube.com/watch?v=xxydY73V9bQ') caption = video.captions['a.en'] srt_content = xml_to_srt(caption.xml_captions) # 可直接写入本地SRT文件 with open('video_subtitle.srt', 'w', encoding='utf-8') as f: f.write(srt_content)
方案2:修改pytube源码适配新结构
找到本地pytube安装目录下的captions.py文件,定位到报错的83行附近,在读取start属性前增加校验逻辑,跳过无效节点:
# 原有报错代码行:start = float(child.attrib["start"]) # 替换为以下内容 if "start" not in child.attrib or "d" not in child.attrib: continue start = float(child.attrib["start"])
该方案缺点是重新安装/升级pytube后修改会失效,需要重新调整。
内容的提问来源于stack exchange,提问作者sponatneous
相关产品推荐
相关产品推荐

