如何从 Python 中的 YouTube 链接中提取视频 ID?
Posted
技术标签:
【中文标题】如何从 Python 中的 YouTube 链接中提取视频 ID?【英文标题】:How can I extract video ID from YouTube's link in Python? 【发布时间】:2011-05-20 09:12:32 【问题描述】:我知道这可以使用 php 的 parse_url
和 parse_str
函数轻松完成:
$subject = "http://www.youtube.com/watch?v=z_AbfPXTKms&NR=1";
$url = parse_url($subject);
parse_str($url['query'], $query);
var_dump($query);
但是如何使用 Python 来实现呢?我可以urlparse
但接下来呢?
【问题讨论】:
【参考方案1】:我创建了没有正则表达式的 youtube id 解析器:
import urlparse
def video_id(value):
"""
Examples:
- http://youtu.be/SA2iWivDJiE
- http://www.youtube.com/watch?v=_oPAwA_Udwc&feature=feedu
- http://www.youtube.com/embed/SA2iWivDJiE
- http://www.youtube.com/v/SA2iWivDJiE?version=3&hl=en_US
"""
query = urlparse.urlparse(value)
if query.hostname == 'youtu.be':
return query.path[1:]
if query.hostname in ('www.youtube.com', 'youtube.com'):
if query.path == '/watch':
p = urlparse.parse_qs(query.query)
return p['v'][0]
if query.path[:7] == '/embed/':
return query.path.split('/')[2]
if query.path[:3] == '/v/':
return query.path.split('/')[2]
# fail?
return None
【讨论】:
这个非常适合解析所有可能的 youtube 链接格式。 您可以使用query.path.startswith('/embed/')
来增加可读性。
上述解决方案运行良好,除了一种情况。 m.youtube.com/?#/watch?v=683hzaj3oc8 如果我也能得到上述场景的解决方案,那将非常有帮助。
"我会完成你开始的工作" ;) :: gist.github.com/kmonsoor/2a1afba4ee127cce50a0【参考方案2】:
Python 有a library for parsing URLs。
import urlparse
url_data = urlparse.urlparse("http://www.youtube.com/watch?v=z_AbfPXTKms&NR=1")
query = urlparse.parse_qs(url_data.query)
video = query["v"][0]
【讨论】:
I can do urlparse but what next?
是的,我知道,但问题出在查询部分。
@decarbo 更新后的答案向您展示了如何仅提取查询字符串中 v
参数的值。
是的,我猜这是最好的解决方案。
仅供参考,这在提交 youtube.com/watch?v=hP54ne1COvY
时不起作用,因为它缺少 http
请注意 urlparse
在 Python3 中被移动到 urllib.parse
类似这样的东西可以解决问题:import urllib.parse as urlparse
【参考方案3】:
这是 Mikhail Kashkin 解决方案的 Python3 版本,添加了场景。
from urllib.parse import urlparse, parse_qs
from contextlib import suppress
# noinspection PyTypeChecker
def get_yt_id(url, ignore_playlist=False):
# Examples:
# - http://youtu.be/SA2iWivDJiE
# - http://www.youtube.com/watch?v=_oPAwA_Udwc&feature=feedu
# - http://www.youtube.com/embed/SA2iWivDJiE
# - http://www.youtube.com/v/SA2iWivDJiE?version=3&hl=en_US
query = urlparse(url)
if query.hostname == 'youtu.be': return query.path[1:]
if query.hostname in 'www.youtube.com', 'youtube.com', 'music.youtube.com':
if not ignore_playlist:
# use case: get playlist id not current video in playlist
with suppress(KeyError):
return parse_qs(query.query)['list'][0]
if query.path == '/watch': return parse_qs(query.query)['v'][0]
if query.path[:7] == '/watch/': return query.path.split('/')[1]
if query.path[:7] == '/embed/': return query.path.split('/')[2]
if query.path[:3] == '/v/': return query.path.split('/')[2]
# returns None for invalid YouTube url
【讨论】:
【参考方案4】:这是正则表达式,它涵盖了这些情况
((?<=(v|V)/)|(?<=be/)|(?<=(\?|\&)v=)|(?<=embed/))([\w-]+)
【讨论】:
为了让它在 python 中工作,我也必须更正语法:((?<=(v|V)/)|(?<=be/)|(?<=(\?|\&)v=)|(?<=embed/))([\w-]+)
。这个解决方案最终成为处理最多案例的解决方案。
/((?<=(v|e|V|vi)\/)|(?<=be\/)|(?<=(\?|\&)v=)|(?<=\/u\/\d+\/)|(?<=(\?|\&)vi=)|(?<=embed\/))([\w-]+)/gi;
与大多数gist.github.com/rodrigoborgesdeoliveira/… 兼容【参考方案5】:
match = re.search(r"youtube\.com/.*v=([^&]*)", "http://www.youtube.com/watch?v=z_AbfPXTKms&test=123")
if match:
result = match.group(1)
else:
result = ""
未经测试。
【讨论】:
【参考方案6】:你可以使用
from urllib.parse import urlparse
url_data = urlparse("https://www.youtube.com/watch?v=RG9TMn1FJzc")
print(url_data.query[2::])
【讨论】:
【参考方案7】:您可以尝试将正则表达式用于 youtube 视频 ID:
# regex for the YouTube ID: "^[^v]+v=(.11).*"
result = re.match('^[^v]+v=(.11).*', url)
print result.group(1)
【讨论】:
此答案来自 2010 年,但也可以修改正则表达式以匹配此模式。be[/](.11).*
【参考方案8】:
不需要正则表达式。在?
拆分,第二个,=
拆分,第二个,&
拆分,第一个。
【讨论】:
工作。您是否知道这种方法是否足够防弹,可以在市场就绪项目中使用而不必担心? 为此使用 urlparse。不要使用字符串拆分或正则表达式自己滚动。 docs.python.org/library/urlparse.html urlparse 提供了一个整体的查询,所以我仍然需要拆分它来获取 ID【参考方案9】:当这些参数可以以任何顺序出现时,拆分字符串是一个非常糟糕的主意。坚持使用 urlparse:
from urllib.parse import parse_qs, urlparse
vid = parse_qs(urlparse(url).query).get('v')
【讨论】:
【参考方案10】:虽然这会进行搜索查询,但会为您提供id
:
from youtube_search import YoutubeSearch
results = YoutubeSearch('search terms', max_results=10).to_json()
print(results)
【讨论】:
【参考方案11】:url = "http://www.youtube.com/watch?v=z_AbfPXTKms&NR=1"
parsed = url.split("?")
videoId = parsed[1]
print(videoId)
这适用于各种 YouTube 视频链接。
【讨论】:
【参考方案12】:我用这个很棒的包pytube
.$ pip install pytube
#Examples
url1='http://youtu.be/SA2iWivDJiE'
url2='http://www.youtube.com/watch?v=_oPAwA_Udwc&feature=feedu'
url3='http://www.youtube.com/embed/SA2iWivDJiE'
url4='http://www.youtube.com/v/SA2iWivDJiE?version=3&hl=en_US'
url5='https://www.youtube.com/watch?v=rTHlyTphWP0&index=6&list=PLjeDyYvG6-40qawYNR4juzvSOg-ezZ2a6'
url6='youtube.com/watch?v=_lOT2p_FCvA'
url7='youtu.be/watch?v=_lOT2p_FCvA'
url8='https://www.youtube.com/watch?time_continue=9&v=n0g-Y0oo5Qs&feature=emb_logo'
urls=[url1,url2,url3,url4,url5,url6,url7,url8]
#Get youtube id
from pytube import extract
for url in urls:
id=extract.video_id(url)
print(id)
输出
SA2iWivDJiE
_oPAwA_Udwc
SA2iWivDJiE
SA2iWivDJiE
rTHlyTphWP0
_lOT2p_FCvA
_lOT2p_FCvA
n0g-Y0oo5Qs
【讨论】:
【参考方案13】:我很晚了,但是我用这个sn-p来获取视频id。
def video_id(url: str) -> str:
"""Extract the ``video_id`` from a YouTube url.
This function supports the following patterns:
- :samp:`https://youtube.com/watch?v=video_id`
- :samp:`https://youtube.com/embed/video_id`
- :samp:`https://youtu.be/video_id`
:param str url:
A YouTube url containing a video id.
:rtype: str
:returns:
YouTube video id.
"""
return regex_search(r"(?:v=|\/)([0-9A-Za-z_-]11).*", url, group=1)
def regex_search(pattern: str, string: str, group: int):
"""Shortcut method to search a string for a given pattern.
:param str pattern:
A regular expression pattern.
:param str string:
A target string to search.
:param int group:
Index of group to return.
:rtype:
str or tuple
:returns:
Substring pattern matches.
"""
regex = re.compile(pattern)
results = regex.search(string)
if not results:
return False
return results.group(group)
【讨论】:
以上是关于如何从 Python 中的 YouTube 链接中提取视频 ID?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Python 中的 Youtube URL 流式传输音频(无需下载)?