首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Youtube视频下载器

Youtube视频下载器
EN

Code Review用户
提问于 2017-05-04 23:03:43
回答 1查看 2.4K关注 0票数 5

这段代码获取一个YouTube视频并下载它。由于YouTube的新算法,它只支持非版权视频。

对结构和逻辑有什么想法吗?我想从我的错误中吸取教训,我刚刚开始用python编写代码。

代码语言:javascript
复制
#!/usr/bin/env python3.5.2

import urllib.request, urllib.parse
import os


def main():
    """
    This code will download only non copyrighted youtube videos due to the new algorithms for accessing video files taht Youtube had changed. 
    Instead of "token" they now use "signature" variable, and "signature" seems to be dependent on either cookie-stored data or IP address of the client
    """
    print("\n                          * * * * * * * * * * * * * * *")
    print("                          *                           *")
    print("                          * Youtube Video Downloader! *")
    print("                          *                           *")
    print("                          * * * * * * * * * * * * * * *\n")
    # make sure to change directory path
    directory = r'C:\Users\SalahGfx\Desktop\DownloadedVideos'

    def get_sourcecode(url):
        return urllib.request.urlopen(url).read()

    def get_info():
        return urllib.parse.parse_qs(get_sourcecode(url).decode('unicode_escape'))

    def get_video_title_path():
        try:
            return os.path.join(directory, '{}.mp4'.format(get_info()['title'][0]))

        except KeyError:
            print('Parsing error, please rerun the code!')

    def get_stream_map():
        return get_info()['url']

    def get_stream_map_list():
        video_links = []
        for video_stream in get_stream_map():
            if "googlevideo" == video_stream.split('/')[2].split('.')[1]:
                video_links.append(video_stream)

            else:
                pass
        return video_links

    def validate_url(url):
        return url.startswith('https://www.youtube.com/')

    def download_video(k):
        return urllib.request.urlretrieve(get_stream_map_list()[k], get_video_title_path())

    def download_hq_video(quality):
        k = 0
        download_video(k)
        print("Downloading {} -----------> {} in {} quality.".format(get_stream_map_list()[k], get_video_title_path(),
                                                                     quality))

    def download_md_video(quality):
        k = 1
        download_video(k)
        print("Downloading {} -----------> {} in {} quality.".format(get_stream_map_list()[k], get_video_title_path(),
                                                                     quality))

    def download_sm_video(quality):
        k = 2
        download_video(k)
        print("Downloading {} -----------> {} in {} quality.".format(get_stream_map_list()[k], get_video_title_path(),
                                                                     quality))

    while True:
        try:
            url, quality = input(
                "Please type a youtube video url and its quality(choose between high, medium and small) and separate them with a space: ").split()

        except ValueError:
            print("Please type the right url and quality.");
            print("Make sure the url start with 'https://www.youtube.com/'");
            print("high - for downloading high quality video");
            print("medium - for downloading medium quality video");
            print("small - for downloading small quality video");
            continue

        if validate_url(url) and quality == 'high':
            get_sourcecode(url)
            download_hq_video(quality)
            break

        elif validate_url(url) and quality == 'medium':
            get_sourcecode(url)
            download_md_video(quality)
            break

        elif validate_url(url) and quality == 'small':
            get_sourcecode(url)
            download_sm_video(quality)
            break

        else:
            break

if __name__ == '__main__':
    main()
EN

回答 1

Code Review用户

回答已采纳

发布于 2017-05-05 16:43:55

我不明白你为什么要/需要三个函数来下载不同质量的视频。在函数和主循环中都有一串重复的逻辑。

然后,我会将所有main特定的代码移到__name__ == __main__部分,因为这就是该部分的目的。

代码语言:javascript
复制
#!/usr/bin/env python3.5.2

import urllib.request, urllib.parse
import os

def get_sourcecode(url):
    return urllib.request.urlopen(url).read()

def get_info():
    return urllib.parse.parse_qs(get_sourcecode(url).decode('unicode_escape'))

def get_video_title_path():
    try:
        return os.path.join(directory, '{}.mp4'.format(get_info()['title'][0]))
    except KeyError:
        print('Parsing error, please rerun the code!')

def get_stream_map_list():
    video_links = []
    for video_stream in get_info()['url']:
        if "googlevideo" == video_stream.split('/')[2].split('.')[1]:
            video_links.append(video_stream)
    return video_links

quality_map = {'small': 0, 'medium': 1, 'high': 2}

def download_video(quality='medium'):
    k = quality_map.get(quality)
    map_list = get_stream_map_list()[k]
    title_path = get_video_title_path()

    print("Downloading {} -----------> {} in {} quality.".format(map_list, title_path, quality))
    return urllib.request.urlretrieve(map_list, title_path)


if __name__ == '__main__':
    print("\n                          * * * * * * * * * * * * * * *")
    print("                          *                           *")
    print("                          * Youtube Video Downloader! *")
    print("                          *                           *")
    print("                          * * * * * * * * * * * * * * *\n")
    # make sure to change directory path
    directory = r'C:\Users\SalahGfx\Desktop\DownloadedVideos'

    while True:
        try:
            url, quality = input(
                "Please type a youtube video url and its quality(choose between high, medium and small) and separate them with a space: ").split()

        except ValueError:
            print("Please type the right url and quality.");
            print("Make sure the url start with 'https://www.youtube.com/'");
            print("high - for downloading high quality video");
            print("medium - for downloading medium quality video");
            print("small - for downloading small quality video");
            continue

        if url.startswith('https://www.youtube.com/') and quality in quality_map:
            get_sourcecode(url)
            download_video(quality)
            break
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/162554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档