如何从 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 【问题描述】:

我知道这可以使用 phpparse_urlparse_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 流式传输音频(无需下载)?

如何从Javascript中的页面中提取链接列表

如何标准化文本文件中的所有 youtube 链接?

在 YouTube 上搜索并返回 Python 中的所有链接

如何在选项菜单中添加 YouTube 链接?

如何通过单击 web 视图中的 youtube 搜索页面链接获取视频 ID