如何将YouTube非标准化字幕时间码正确解析为datetime对象
问题:解析YouTube字幕时间码为datetime对象时的格式错误
尝试将YouTube字幕的时间码字符串转换为datetime对象,使用dateutil.parser.parse时出现解析逻辑错误:
from datetime import datetime from dateutil import parser timecodes = ['0:00', '0:01', '1:01', '10:01', '1:10:01'] for timecode in timecodes: dt = parser.parse(timecode) print(dt)
这些时间码是YouTube生成的累计时长格式:
0:00 # 0分钟,0秒 0:01 # 0分钟,1秒 1:01 # 1分钟,1秒 10:01 # 10分钟,1秒 1:10:01 # 1小时,10分钟,1秒
但解析结果不符合预期:
2022-10-24 00:00:00 # 0分钟0秒(正确) 2022-10-24 00:01:00 # 实际应为1分钟0秒,被解析为0小时1分钟0秒 2022-10-24 01:01:00 # 实际应为1分钟1秒,被解析为1小时1分钟0秒 2022-10-24 10:01:00 # 实际应为10分钟1秒,被解析为10小时1分钟0秒 2022-10-24 01:10:01 # 1小时10分钟1秒(正确)
核心问题:短格式时间码(不含小时)被parser.parse错误识别为「小时:分钟」,而非预期的「分钟:秒」。需要实现动态解析,让短格式默认按分秒处理,或调整时间码适配解析方法。
方法1:预处理时间码,补全小时前缀
根据冒号数量判断格式,给只有1个冒号的时间码补「0:」前缀,统一为「时:分:秒」格式后再解析:
from datetime import datetime from dateutil import parser timecodes = ['0:00', '0:01', '1:01', '10:01', '1:10:01'] for timecode in timecodes: # 补全格式:只有1个冒号时,添加0小时前缀 if timecode.count(':') == 1: adjusted_timecode = f"0:{timecode}" else: adjusted_timecode = timecode dt = parser.parse(adjusted_timecode) print(f"{timecode} -> {dt}")
输出结果:
0:00 -> 2022-10-24 00:00:00 0:01 -> 2022-10-24 00:00:01 1:01 -> 2022-10-24 00:01:01 10:01 -> 2022-10-24 00:10:01 1:10:01 -> 2022-10-24 01:10:01
方法2:手动解析时间码,直接构建datetime对象
不依赖dateutil.parser,手动拆分时间码的时、分、秒,基于基准日期构建datetime:
from datetime import datetime timecodes = ['0:00', '0:01', '1:01', '10:01', '1:10:01'] # 基准日期,可根据需求修改 base_date = datetime(2022, 10, 24) for timecode in timecodes: parts = list(map(int, timecode.split(':'))) if len(parts) == 2: minutes, seconds = parts hours = 0 elif len(parts) == 3: hours, minutes, seconds = parts else: # 处理异常格式,这里可根据需求调整 hours = minutes = seconds = 0 dt = base_date.replace(hour=hours, minute=minutes, second=seconds) print(f"{timecode} -> {dt}")
输出结果和方法1一致,这种方式更可控,避免第三方库的自动解析歧义。
补充:仅需时长时使用timedelta
如果不需要绑定具体日期,只是计算累计时长,可直接使用datetime.timedelta对象:
from datetime import timedelta timecodes = ['0:00', '0:01', '1:01', '10:01', '1:10:01'] for timecode in timecodes: parts = list(map(int, timecode.split(':'))) if len(parts) == 2: td = timedelta(minutes=parts[0], seconds=parts[1]) else: td = timedelta(hours=parts[0], minutes=parts[1], seconds=parts[2]) print(f"{timecode} -> {td}")
输出:
0:00 -> 0:00:00 0:01 -> 0:00:01 1:01 -> 0:01:01 10:01 -> 0:10:01 1:10:01 -> 1:10:01
内容的提问来源于stack exchange,提问作者P A N
相关产品推荐
相关产品推荐

