Python Script to Download YouTube Videos

Filed Under: Python
Python Script To Download YouTube Videos

We can use pytube Python library to download YouTube videos. It’s a simple and lightweight Python module with no third-party dependencies.

Installing pytube Library

If you look at the PyPI, there are two types of pytube libraries: pytube and pytube3. When I installed pytube library, I got error in importing its YouTube class.

# pip install pytube

# python3.7

>>> from pytube import YouTube
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pytube/", line 16, in <module>
    from pytube.streams import Stream
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pytube/", line 17, in <module>
    from pytube import extract
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pytube/", line 7, in <module>
    from pytube.compat import quote
ImportError: cannot import name 'quote' from 'pytube.compat' (/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pytube/

I didn’t faced any issues with pytube3 library.

# pip install pytube3

# python3.7

>>> from pytube import YouTube

So, I would recommend you to use pytube3 library. I am using the same in this tutorial.

Python Script to Download a YouTube Video

The first step is to import the YouTube class from the pytube module.

from pytube import YouTube

Next step is to create the YouTube object by passing the YouTube video URL.

youtube_video_url = ''

yt_obj = YouTube(youtube_video_url)

The YouTube object opens different streams from the YouTube video URL. We can get all the stream information using the following code.

for stream in yt_obj.streams:

It will produce the following output.

<Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">
<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">
<Stream: itag="137" mime_type="video/mp4" res="1080p" fps="30fps" vcodec="avc1.64001e" progressive="False" type="video">
<Stream: itag="248" mime_type="video/webm" res="1080p" fps="30fps" vcodec="vp9" progressive="False" type="video">
<Stream: itag="299" mime_type="video/mp4" res="1080p" fps="60fps" vcodec="avc1.64002a" progressive="False" type="video">
<Stream: itag="303" mime_type="video/webm" res="1080p" fps="60fps" vcodec="vp9" progressive="False" type="video">
<Stream: itag="136" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.4d4016" progressive="False" type="video">
<Stream: itag="247" mime_type="video/webm" res="720p" fps="30fps" vcodec="vp9" progressive="False" type="video">
<Stream: itag="298" mime_type="video/mp4" res="720p" fps="60fps" vcodec="avc1.4d4016" progressive="False" type="video">
<Stream: itag="302" mime_type="video/webm" res="720p" fps="60fps" vcodec="vp9" progressive="False" type="video">
<Stream: itag="135" mime_type="video/mp4" res="480p" fps="30fps" vcodec="avc1.4d4014" progressive="False" type="video">
<Stream: itag="244" mime_type="video/webm" res="480p" fps="30fps" vcodec="vp9" progressive="False" type="video">
<Stream: itag="134" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.4d401e" progressive="False" type="video">
<Stream: itag="243" mime_type="video/webm" res="360p" fps="30fps" vcodec="vp9" progressive="False" type="video">
<Stream: itag="133" mime_type="video/mp4" res="240p" fps="30fps" vcodec="avc1.4d400c" progressive="False" type="video">
<Stream: itag="242" mime_type="video/webm" res="240p" fps="30fps" vcodec="vp9" progressive="False" type="video">
<Stream: itag="160" mime_type="video/mp4" res="144p" fps="30fps" vcodec="avc1.4d400b" progressive="False" type="video">
<Stream: itag="278" mime_type="video/webm" res="144p" fps="30fps" vcodec="vp9" progressive="False" type="video">
<Stream: itag="140" mime_type="audio/mp4" abr="128kbps" acodec="mp4a.40.2" progressive="False" type="audio">
<Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus" progressive="False" type="audio">

Few important Points:

  • The “progressive” stream contains the file having both audio and video.
  • The “adaptive” stream contains either audio or video.
  • The “mime_type”, “res”, and “fps” attributes can be used to filter the stream that we want to download.

We can use the filter() function to extract only specific streams. This is useful when we want to download all the different resolutions of the YouTube video.

filters = yt_obj.streams.filter(progressive=True, file_extension='mp4')

for mp4_filter in filters:


<Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">
<Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2" progressive="True" type="video">

There are few useful functions to get the highest and lowest resolution videos.

filters = yt_obj.streams.filter(progressive=True, file_extension='mp4')


The final step is to call the download() method on the specific stream to download the YouTube video.


The video will be downloaded in the current working directory. The video file name will be the title of the YouTube video.

Complete Code to Download the Highest Resolution YouTube video

from pytube import YouTube

youtube_video_url = ''

    yt_obj = YouTube(youtube_video_url)

    filters = yt_obj.streams.filter(progressive=True, file_extension='mp4')

    # download the highest quality video
    print('Video Downloaded Successfully')
except Exception as e:

Specifying the Downloaded YouTube Video File Location and Name

The download() function accepts different parameters to change the video file location and name.

download(output_path='/Users/pankaj/temp', filename='yt_video.mp4')

Downloading Only Audio from the YouTube Video URL

Sometimes we want only the audio from the YouTube video URL. We can use the get_audio_only() function for this.

from pytube import YouTube

youtube_video_url = ''

    yt_obj = YouTube(youtube_video_url)

    yt_obj.streams.get_audio_only().download(output_path='/Users/pankaj/temp', filename='audio')
    print('YouTube video audio downloaded successfully')
except Exception as e:

Getting YouTube Video Metadata Information

We can also get the YouTube video metadata information such as title, description, video length, rating, author name, views count, etc.

from pytube import YouTube

    yt_obj = YouTube('')

    print(f'Video Title is {yt_obj.title}')
    print(f'Video Length is {yt_obj.length} seconds')
    print(f'Video Description is {yt_obj.description}')
    print(f'Video Rating is {yt_obj.rating}')
    print(f'Video Views Count is {yt_obj.views}')
    print(f'Video Author is {}')

except Exception as e:

Downloading Multiple YouTube Videos

If you have to download multiple videos, we can extend the program easily.

from pytube import YouTube

list_urls = ['',

for url in list_urls:

        yt_obj = YouTube(url)

    except Exception as e:
        raise Exception('Some exception occurred.')
    print('All YouTube videos downloaded successfully.')

If you are specifying the filename and directory parameters in the download() function, make sure they are different for each video to avoid overriding.

Downloading All the Videos from a YouTube Playlist

We can use the Playlist class to download all the videos from a YouTube playlist.

from pytube import Playlist

    playlist = Playlist('')


except Exception as e:


Python pytube library is simple and powerful. We can download YouTube videos in different resolutions, only audio, and all the videos from a playlist.

Reference: PyPI pytube3 page


  1. Sampathkumar says:

    Its really helpful thanks for this post

  2. Neelima Gopisetti says:

    Thanks for the solution. The above approach is able to download only 100 videos in a playlist even though the playlist has 100+ videos included in it.

    1. Pratik Sharma says:

      For some reason, There is a limit of 100 video for playlist (from youtube). You would have to break the playlist.

Comments are closed.

Generic selectors
Exact matches only
Search in title
Search in content