Mor*_*lde 13 python youtube-api
为了感兴趣,我想将视频持续时间从YouTubes转换ISO 8601
为秒.为了将来证明我的解决方案,我选择了一个非常长的视频来测试它.
API提供此期限 - "duration": "P1W2DT6H21M32S"
我尝试使用stackoverflow.com/questions/969285中的dateutil
建议解析此持续时间.
import dateutil.parser
duration = = dateutil.parser.parse('P1W2DT6H21M32S')
Run Code Online (Sandbox Code Playgroud)
这引发了一个例外
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'int'
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
jlm*_*ald 21
Python的内置dateutil模块仅支持解析ISO 8601日期,而不支持ISO 8601持续时间.为此,您可以使用"isodate"库(在https://pypi.python.org/pypi/isodate中的pypi中- 通过pip或easy_install安装).该库完全支持ISO 8601持续时间,将它们转换为datetime.timedelta对象.所以一旦你导入了库,它就像下面这样简单:
dur=isodate.parse_duration('P1W2DT6H21M32S')
print dur.total_seconds()
Run Code Online (Sandbox Code Playgroud)
适用于python 2.7+.这里是针对Youtube v3问题的JavaScript单行代码.
import re
def YTDurationToSeconds(duration):
match = re.match('PT(\d+H)?(\d+M)?(\d+S)?', duration).groups()
hours = _js_parseInt(match[0]) if match[0] else 0
minutes = _js_parseInt(match[1]) if match[1] else 0
seconds = _js_parseInt(match[2]) if match[2] else 0
return hours * 3600 + minutes * 60 + seconds
# js-like parseInt
# https://gist.github.com/douglasmiranda/2174255
def _js_parseInt(string):
return int(''.join([x for x in string if x.isdigit()]))
# example output
YTDurationToSeconds(u'PT15M33S')
# 933
Run Code Online (Sandbox Code Playgroud)
处理iso8061持续时间格式以扩展Youtube使用长达数小时
这是我的答案,它需要9000的正则表达式解决方案(谢谢 - 对正则表达式的惊人掌握!)并完成了原始海报的 YouTube 用例的工作,即将小时、分钟和秒转换为秒。我使用了.groups()
而不是.groupdict()
,然后是几个精心构建的列表推导式。
import re
def yt_time(duration="P1W2DT6H21M32S"):
"""
Converts YouTube duration (ISO 8061)
into Seconds
see http://en.wikipedia.org/wiki/ISO_8601#Durations
"""
ISO_8601 = re.compile(
'P' # designates a period
'(?:(?P<years>\d+)Y)?' # years
'(?:(?P<months>\d+)M)?' # months
'(?:(?P<weeks>\d+)W)?' # weeks
'(?:(?P<days>\d+)D)?' # days
'(?:T' # time part must begin with a T
'(?:(?P<hours>\d+)H)?' # hours
'(?:(?P<minutes>\d+)M)?' # minutes
'(?:(?P<seconds>\d+)S)?' # seconds
')?') # end of time part
# Convert regex matches into a short list of time units
units = list(ISO_8601.match(duration).groups()[-3:])
# Put list in ascending order & remove 'None' types
units = list(reversed([int(x) if x != None else 0 for x in units]))
# Do the maths
return sum([x*60**units.index(x) for x in units])
Run Code Online (Sandbox Code Playgroud)
很抱歉没有发布更高的帖子 - 这里仍然是新的,没有足够的声望点来添加评论。
视频不是1周2天6小时21分32秒长吗?
Youtube显示为222小时21分17秒;1 * 7 * 24 + 2 * 24 + 6 = 222。不过,我不知道 17 秒与 32 秒的差异从何而来;也可能是舍入误差。
在我看来,为此编写一个解析器并不难。不幸的是dateutil
,似乎没有解析间隔,只有日期时间点。
更新:
我看到有一个用于此目的的包,但作为正则表达式的强大功能、简洁性和难以理解的语法的示例,这里有一个解析器:
import re
# see http://en.wikipedia.org/wiki/ISO_8601#Durations
ISO_8601_period_rx = re.compile(
'P' # designates a period
'(?:(?P<years>\d+)Y)?' # years
'(?:(?P<months>\d+)M)?' # months
'(?:(?P<weeks>\d+)W)?' # weeks
'(?:(?P<days>\d+)D)?' # days
'(?:T' # time part must begin with a T
'(?:(?P<hours>\d+)H)?' # hourss
'(?:(?P<minutes>\d+)M)?' # minutes
'(?:(?P<seconds>\d+)S)?' # seconds
')?' # end of time part
)
from pprint import pprint
pprint(ISO_8601_period_rx.match('P1W2DT6H21M32S').groupdict())
# {'days': '2',
# 'hours': '6',
# 'minutes': '21',
# 'months': None,
# 'seconds': '32',
# 'weeks': '1',
# 'years': None}
Run Code Online (Sandbox Code Playgroud)
我故意不根据这些数据计算确切的秒数。它看起来微不足道(见上文),但实际上并非如此。例如,从 1 月 1 日起 2 个月的距离为 58 天 (30+28) 或 59 天 (30+29),具体取决于年份,而从 3 月 1 日起总是 61 天。正确的日历实施应该考虑到所有这些;对于 YouTube 剪辑长度计算,它一定是过大的。
归档时间: |
|
查看次数: |
4230 次 |
最近记录: |