【问题标题】:Get YouTube video ID from URL with Python and Regex使用 Python 和 Regex 从 URL 获取 YouTube 视频 ID
【发布时间】:2016-04-22 08:31:31
【问题描述】:

我想检索 YouTube URL 的视频 ID 部分,它是 HTML 锚元素的一部分,例如使用正则表达式:

<a href="http://www.youtube.com/watch?v=NC2blnl0WTE">Some text</a>

我已经四处寻找一些解决方案。我从一个 Javascript 解决方案中找到了一个,它从 url 中获取视频 ID,如下所示:

/https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\S*[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig

我想在 Python 中使用它,因为它支持 YouTube 网址的各种变化。我在我的 Python 脚本中实现了它:

string = re.sub(r'https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\S*[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:[\'"][^<>]*>|<\/a>))[?=&+%\w.-]*', r'\1', string)

而且我没有替代品。我从正则表达式中删除了//ig,因为它们仅在 Javascript 中,但我仍然无法获取视频 ID。一旦我能够拿到 ID,我就可以轻松地更改正则表达式以删除锚元素。

我的解决方案做错了什么?谢谢。

【问题讨论】:

    标签: javascript python regex


    【解决方案1】:

    我不认为这(向右滚动以查看由^^ 表示的部分)应该是负面的前瞻:

    https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\S*[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*
                                                                                                             ^^
    

    我认为它应该是一个非捕获组(即?! 应该是?:)。

    >>> import re
    
    >>> html = '<a href="http://www.youtube.com/watch?v=NC2blnl0WTE">Some text</a>'
    >>> pattern = re.compile(r"""https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\S*[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?:[?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*""", re.IGNORECASE)
    >>> re.search(pattern,  html).groups()
    ('NC2blnl0WTE',)
    

    编辑:请注意,我还必须使用re.IGNORECASE。这是因为正则表达式按原样与www.youtube.com 中的www 不匹配。您需要 [0-9A-Z-] 成为 [0-9A-Za-z-]。但是,忽略大小写会更安全,这样您就不必担心 URL 中的其他文本。

    EDIT2:作为否定前瞻,这意味着当 URL 后面跟着锚标记的结束和结束 ("&gt;blah blah blah&lt;/a&gt;) 时,您将永远无法匹配。

    【讨论】:

      【解决方案2】:

      我使用类似下面的东西,基于Youtube I.D parsing for new URL formatsPython regex convert youtube url to youtube video

      import re
      
      test_links = """
          'http://www.youtube.com/watch?v=5Y6HSHwhVlY',
          'http://www.youtube.com/watch?/watch?other_param&v=5Y6HSHwhVlY',
          'http://www.youtube.com/v/5Y6HSHwhVlY',
          'http://youtu.be/5Y6HSHwhVlY', 
          'http://www.youtube.com/embed/5Y6HSHwhVlY?rel=0" frameborder="0"',
          'http://m.youtube.com/v/5Y6HSHwhVlY',
          'https://www.youtube-nocookie.com/v/5Y6HSHwhVlY?version=3&amp;hl=en_US',
          'http://www.youtube.com/',
          'http://www.youtube.com/?feature=ytca
      """
      
      pattern = r'(?:https?:\/\/)?(?:[0-9A-Z-]+\.)?(?:youtube|youtu|youtube-nocookie)\.(?:com|be)\/(?:watch\?v=|watch\?.+&v=|embed\/|v\/|.+\?v=)?([^&=\n%\?]{11})'
      
      result = re.findall(pattern, test_links, re.MULTILINE | re.IGNORECASE)
      
      print(result)
      

      但我真的不知道我是否是最新的。

      编辑

      允许所有子域

      【讨论】:

        猜你喜欢
        • 2012-03-24
        • 2011-03-24
        • 1970-01-01
        • 2011-07-22
        • 2011-11-05
        • 2016-01-21
        • 2012-05-22
        • 2011-03-28
        相关资源
        最近更新 更多