[Python] Download YouTube Videos automatically
Tags: python, vscode, tutorial, productivity
Published: 2022-08-19 09:42:37

A demo for downloading YouTube videos automatically It’s a toy project just for play. This is not the most effective way, definitely, but it is simple enough for Python beginners.

**Requirements:**

- Window 7+
- Python 3.7+
- VS Code  

**Setup**
Install Pytube:
```
pip install pytube
```
**Install Clicknium:**
Search for Clicknium in the Visual Studio Code Extension marketplace:
  ![vscex](https://s1.328888.xyz/2022/08/19/BmQ8U.png)  
Follow the welcome page to finish the configuration:  
![welcome](https://s1.328888.xyz/2022/08/19/Bmr6R.png)  
**Start a web browser:**  
Create a Python file with VS Code, such as, youtube.py  
```python
from clicknium import clicknium as cc
def main():
    tab = cc.chrome.open("https://www.youtube.com")

if __name__ == "__main__":
    main()
```
Press F5 to run the code. It will open the Chrome browser and take you to the YouTube home page.

**Capture:**  
Go to a Youtuber’s home page, like Tayler Swift's, for example, and get the videos’ links. Something like 5-steps to put an elephant into a refrigerator:

1. Input Taylor Swift in the search bar.
2. Click the search button.
3. Click Taylor’s link to step into Taylor’s homepage.
4. Click to step inside the video page.

There are four related UI elements:  
- Search box
- Search button
- Name in the search result
- video tab  

Clicknium uses a locator (aka selector) to find the UI elements. It provides a recorder to generate a locator. We can use the above code to open a browser and go back to VS Code to start the recorder.  
![locatorcapture](https://s1.328888.xyz/2022/08/19/BmXFX.png)  
Hover over an element on the screen, press Ctrl and click it to automatically generate a locator for the UI element. Capture the search box, the search button, and Taylor's name in the upper right corner.  
![searchts](https://s1.328888.xyz/2022/08/19/BmREr.png)  

Each capture will generate a locator target for the UI elements. You can also rename the locator to a meaningful name. Click the complete button and get back to VS Code after the capture.  
![recorder](https://s1.328888.xyz/2022/08/19/BmZGK.png)

Pass the locator to find_element function to get the UI elements. Then use the set_text function to text ”Taylor Swift” into the search box. The next line uses the same way to get the search button and uses the click function to present the mouse click. Run the above code and we can get into the homepage. Use the same way to step into the video list.  

```python
from clicknium import clicknium as cc, locator
from clicknium.common.enums import *

def main():
    tab = cc.chrome.open("https://www.youtube.com")
    tab.find_element(locator.chrome.youtube.searchBar).set_text(
        "Taylor Swift", by='sendkey-after-click')
    tab.find_element(locator.chrome.youtube.button_search_icon_legacy).click()
    tab.find_element(locator.chrome.youtube.TS).click()

if __name__ == "__main__":
    main()
```
We have to get every address for the videos in the above image. The address can be gotten from the locator properties, but it would be boring if we needed to generate so many locators. We can use the capturing similar elements function provided by Clicknium Recorder. Click the similar elements button and use the same method for capturing a single element. Clicknium will auto-detect the similar elements and generate one locator to target all similar UI elements.  
![similarloc](https://s1.328888.xyz/2022/08/19/BmiUm.png)

```python
    tab = cc.chrome.open("https://www.youtube.com")
    tab.find_element(locator.chrome.youtube.searchBar).set_text(
        "Taylor Swift", by='sendkey-after-click')
    tab.find_element(locator.chrome.youtube.button_search_icon_legacy).click()
    tab.find_element(locator.chrome.youtube.TS).click()
    tab.find_element(locator.chrome.youtube.div_video).click()
    tab.wait_appear(locator.chrome.youtube.a_video_title)# wait untill loading videos finish
    vidioTitles = tab.find_elements(locator.chrome.youtube.a_video_title)
```
Because of the asynchronous loading of the video list, we have to use wait_appear to wait for the UI elements to appear. Because the locator targeted multiple videos, use find_elements to get an array of UI elements. A video URL can be gotten from the YouTube address by appending a related path to the video got from href.

Use Pytube to get videos by video URLs. Pytube allows downloading videos according to a given resolution. You may notice that some streams listed have both a video codec and an audio codec, while others have just video or just audio for the highest quality streams. More details [Working with Streams and StreamQuery](https://pytube.io/en/latest/user/streams.html#filtering-by-streaming-method)

Code:

```python
from pytube import YouTube
from clicknium import clicknium as cc, locator
from clicknium.common.enums import *

def downloadVideo(url):
    SAVE_PATH = "C:\\Users\\Kay\\Downloads\\Youtube"
    try:
        yt = YouTube(url)
        yt.streams.filter(res="1080p").first().download(output_path=SAVE_PATH)
    except:
        print("Connection Error")  # to handle exception

    # filters out all the files with "mp4" extension
    print('Task Completed!')


def main():
    urlArrary = []
    tab = cc.chrome.open("https://www.youtube.com")
    tab.find_element(locator.chrome.youtube.searchBar).set_text(
        "Taylor Swift", by='sendkey-after-click')
    tab.find_element(locator.chrome.youtube.button_search_icon_legacy).click()
    tab.find_element(locator.chrome.youtube.TS).click()
    tab.find_element(locator.chrome.youtube.div_video).click()
    tab.wait_appear(locator.chrome.youtube.a_video_title)
    videoTitles = tab.find_elements(locator.chrome.youtube.a_video_title)
    for locat in videoTitles:
        url = "https://www.youtube.com" + locat.get_property("href")
        urlArrary.append(url)
    tab.close()

    for v in urlArrary:
        downloadVideo(v)


if __name__ == "__main__":
    main()
```