Search code examples
pythonpython-3.xexceptionexceptpytube

PyTube: PrivateVideo exception not working


I wrote a code that will print all videos' name on the playlist. The problem is when it tries to print the name of the video that is private. I wrote an exception from Github that the owner wrote but it still doesn't work. It should skip this one video and go to another one but it doesn't and the program crashes. Here is my code:

import pytube
from pytube.exceptions import VideoPrivate

pl = pytube.Playlist("https://www.youtube.com/playlist?list=PLB1PGaMZkETOixDfsnKIOkfJS_cToCHSt")


for video in pl.videos:
    try:
        print(video.title)
    except VideoPrivate:
        continue

Error output:

python playlist.py
One Direction - Steal My Girl
One Direction - Drag Me Down (Official Video)
One Direction - Story of My Life
One Direction - Night Changes
One Direction - Perfect (Official Video)
Traceback (most recent call last):
  File "playlist.py", line 6, in <module>
    for video in pl.videos:
  File "C:\Users\Elton\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\contrib\playlist.py", line 222, in videos
    yield from (YouTube(url) for url in self.video_urls)
  File "C:\Users\Elton\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\contrib\playlist.py", line 222, in <genexpr>
    yield from (YouTube(url) for url in self.video_urls)
  File "C:\Users\Elton\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\__main__.py", line 104, in __init__
    self.prefetch()
  File "C:\Users\Elton\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\__main__.py", line 203, in prefetch
    self.check_availability()
  File "C:\Users\Elton\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\__main__.py", line 137, in check_availability
    raise VideoPrivate(video_id=self.video_id)
pytube.exceptions.VideoPrivate: 8fGmghrkLco is a private video

Solution

  • The exception is generated outside of the try/catch. It is actually being raised when the next item of pl.videos is yield.

    @property
    def videos(self) -> Iterable[YouTube]:
        """Yields YouTube objects of videos in this playlist
    
        :Yields: YouTube
        """
        yield from (YouTube(url) for url in self.video_urls)
    

    Instead of calling videos, you may use video_urls

    for video in pl.video_urls:
        try:
            print(YouTube(video).title)
        except VideoUnavailable:
            continue
    

    Here we are using VideoUnavailable which is the baseClass for VideoPrivate

    You will need the following imports:

    import pytube
    from pytube.exceptions import VideoUnavailable
    from pytube import YouTube
    

    Output:

    One Direction - Steal My Girl
    One Direction - Drag Me Down (Official Video)
    One Direction - Story of My Life
    One Direction - Night Changes
    One Direction - Perfect (Official Video)
    One Direction - You & I