无法下载 YouTube 视频

新手上路,请多包涵

我在自动检索 YouTube 视频时遇到问题。这是代码。问题是最后一部分。 download = urllib.request.urlopen(download_url).read()

 # YouTube video download script
# 10n1z3d[at]w[dot]cn

import urllib.request
import sys

print("\n--------------------------")
print (" YouTube Video Downloader")
print ("--------------------------\n")

try:
    video_url = sys.argv[1]
except:
    video_url = input('[+] Enter video URL: ')

print("[+] Connecting...")
try:
    if(video_url.endswith('&feature=related')):
        video_id = video_url.split('www.youtube.com/watch?v=')[1].split('&feature=related')[0]
    elif(video_url.endswith('&feature=dir')):
        video_id = video_url.split('www.youtube.com/watch?v=')[1].split('&feature=dir')[0]
    elif(video_url.endswith('&feature=fvst')):
        video_id = video_url.split('www.youtube.com/watch?v=')[1].split('&feature=fvst')[0]
    elif(video_url.endswith('&feature=channel_page')):
        video_id = video_url.split('www.youtube.com/watch?v=')[1].split('&feature=channel_page')[0]
    else:
        video_id = video_url.split('www.youtube.com/watch?v=')[1]
except:
    print("[-] Invalid URL.")
    exit(1)

print("[+] Parsing token...")
try:
    url = str(urllib.request.urlopen('http://www.youtube.com/get_video_info?&video_id=' + video_id).read())
    token_value = url.split('video_id=' + video_id + '&token=')[1].split('&thumbnail_url')[0]

    download_url = "http://www.youtube.com/get_video?video_id=" + video_id + "&t=" + token_value + "&fmt=18"
except:
    url = str(urllib.request.urlopen('www.youtube.com/watch?v=' + video_id))
    exit(1)

v_url = str(urllib.request.urlopen('http://' + video_url).read())
video_title = v_url.split('"rv.2.title": "')[1].split('", "rv.4.rating"')[0]
if '"' in video_title:
    video_title = video_title.replace('"', '"')
elif '&' in video_title:
    video_title = video_title.replace('&', '&')

print("[+] Downloading " + '"' + video_title + '"...')
try:
    print(download_url)
    file = open(video_title + '.mp4', 'wb')
    download = urllib.request.urlopen(download_url).read()
    print(download)
    for line in download:
        file.write(line)
        file.close()
except:
    print("[-] Error downloading. Quitting.")
    exit(1)

print("\n[+] Done. The video is saved to the current working directory(cwd).\n")

出现错误消息(感谢 Wooble):

 Traceback (most recent call last):
  File "C:/Python31/MyLib/DrawingBoard/youtube_download-.py", line 52, in <module>
    download = urllib.request.urlopen(download_url).read()
  File "C:\Python31\lib\urllib\request.py", line 119, in urlopen
    return _opener.open(url, data, timeout)
  File "C:\Python31\lib\urllib\request.py", line 353, in open
    response = meth(req, response)
  File "C:\Python31\lib\urllib\request.py", line 465, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python31\lib\urllib\request.py", line 385, in error
    result = self._call_chain(*args)
  File "C:\Python31\lib\urllib\request.py", line 325, in _call_chain
    result = func(*args)
  File "C:\Python31\lib\urllib\request.py", line 560, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "C:\Python31\lib\urllib\request.py", line 353, in open
    response = meth(req, response)
  File "C:\Python31\lib\urllib\request.py", line 465, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python31\lib\urllib\request.py", line 391, in error
    return self._call_chain(*args)
  File "C:\Python31\lib\urllib\request.py", line 325, in _call_chain
    result = func(*args)
  File "C:\Python31\lib\urllib\request.py", line 473, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

原文由 Kev 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

原始问题的代码依赖于关于 YouTube 页面和 URL 内容的几个假设(以“url.split(‘something=’)[1]”等结构表示),这些假设可能并不总是正确的。我对其进行了测试,它甚至可能取决于页面上显示的相关视频。您可能已经被这些细节中的任何一个绊倒了。

这是一个更清晰的版本,它使用 urllib 来解析 URL 和查询字符串,并成功下载了视频。为了清楚起见,我删除了一些 try/except ,它们除了退出外没有做太多事情。顺便说一句,它通过从保存视频的文件名中删除非 ASCII 字符来处理 Unicode 视频标题。它还可以获取任意数量的 YouTube 网址并将它们全部下载。最后,它将其用户代理屏蔽为 Mac 版 Chrome(这是我目前使用的)。

 #!/usr/bin/env python3

import sys
import urllib.request
from urllib.request import urlopen, FancyURLopener
from urllib.parse import urlparse, parse_qs, unquote

class UndercoverURLopener(FancyURLopener):
    version = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.9 Safari/533.2"

urllib.request._urlopener = UndercoverURLopener()

def youtube_download(video_url):
    video_id = parse_qs(urlparse(video_url).query)['v'][0]

    url_data = urlopen('http://www.youtube.com/get_video_info?&video_id=' + video_id).read()
    url_info = parse_qs(unquote(url_data.decode('utf-8')))
    token_value = url_info['token'][0]

    download_url = "http://www.youtube.com/get_video?video_id={0}&t={1}&fmt=18".format(
        video_id, token_value)

    video_title = url_info['title'][0] if 'title' in url_info else ''
    # Unicode filenames are more trouble than they're worth
    filename = video_title.encode('ascii', 'ignore').decode('ascii').replace("/", "-") + '.mp4'

    print("\t Downloading '{}' to '{}'...".format(video_title, filename))

    try:
        download = urlopen(download_url).read()
        f = open(filename, 'wb')
        f.write(download)
        f.close()
    except Exception as e:
        print("\t Download failed! {}".format(str(e)))
        print("\t Skipping...")
    else:
        print("\t Done.")

def main():
    print("\n--------------------------")
    print (" YouTube Video Downloader")
    print ("--------------------------\n")

    try:
        video_urls = sys.argv[1:]
    except:
        video_urls = input('Enter (space-separated) video URLs: ')

    for u in video_urls:
        youtube_download(u)
    print("\n Done.")

if __name__ == '__main__':
    main()

原文由 rbp 发布,翻译遵循 CC BY-SA 4.0 许可协议

我将厚颜无耻地插入 我的脚本,该脚本会自动检查有效格式,自动为视频选择最佳质量格式,并适用于 YouTube 页面的 Flash 和 HTML5 变体(以及 Vimeo )。

如果您编写了该脚本,那么请查看我的源代码以获取灵感并随意窃取一些代码。我挑战你请写出更好的东西。开源在竞争中茁壮成长!

但是,如果您复制了该脚本并只是想让它工作,我建议您试试我的脚本,看看它是否更适合您。您可以从命令行作为脚本访问它,甚至可以作为另一个 Python 文件中的模块访问它。

原文由 Jake Wharton 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题