Simple YouTube down loader using Selenium

Posts 16 of 6 · Page 1 of 1
Simple YouTube down loader using Selenium
Hey all,

I decided to create a program that downloads music for me... I had a notepad file that when I heard a good song on pandora or spotify I would add it into the notepad file to eventually download it later. This file grew pretty large to over 800 songs and I couldn't be bothered with downloading each one individually. I looked around for some auto music downloaders but there wasn't any that I could find that would take a list of songs and download them. I decided to make my own with the use of Selenium instead.

A few things that are going to be required for you to be able to run this script.
  • Selenium Nugget package
  • Chrome Driver (I use adblocker so that's why I suggest chrome but firefox, ie or safari will work too).


So here is the format of my Song list that I had saved:
Code:
Animal - Miike Snow
Lasso - Phoenix
Broken Crown - Mumford & Sons
Mad World - Gary Jules
Amazing Grace - The Dropkick Murphys
Let Her Go - Passenger
Demons - Imagine Dragons
Girlfriend - Phoenix
Drunken Sailor - The Irish Rovers
Intro - The xx
Come with me now - Kongos
Something I need - One Republic
Note that your list doesn't have to be in this format, I just wrote down song name + artist is all. It also made it easier for me to download songs based on the way that selenium works using this format.

So once I had the list compiled, I started working on the code. I have removed my relative path to the songlist.txt so just modify it with where ever your file is located.

Here is the code for the program:

Code:
using System;
using System.Collections.ObjectModel;
using System****;
using System.Linq;
using System.Threading;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

namespace AutoMusicDownloader
{
    class Program
    {
        private static void Main(string[] args)
        {
            //TODO: Replace with your own relative path
            var test = File.ReadAllLines(@"C:\Users\Desktop\AutoMusicDownloader\AutoMusicDownloader\Song List.txt").ToList();

            //TODO: Replace with your own relative path
            var options = new ChromeOptions();
            options.AddExtension(@"C:\Users\Desktop\AutoMusicDownloader\AutoMusicDownloader\Adblock-Plus_v1.11.crx");
            
            IWebDriver driver = new ChromeDriver(options);
            driver.Manage().Window.Maximize();

            foreach (var line in test)
            {
                #region Youtube elements

                driver.Navigate().GoToUrl("https://www.youtube.com/");
                driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));

                IWebElement youtubeSearchBox = driver.FindElement(By.XPath(".//*[@id='masthead-search-term']"));
                youtubeSearchBox.Clear();
                youtubeSearchBo*****ndKeys(line);

                IWebElement youtubeSearchbutton = driver.FindElement(By.XPath(".//*[@id='search-btn']"));
                youtubeSearchbutton.Click();

                Thread.Sleep(1000);
                driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));
                Thread.Sleep(1000);

                ReadOnlyCollection<IWebElement> testy = driver.FindElements(By.ClassName("item-section"));
                Thread.Sleep(1000);
                driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));
                testy.FirstOrDefault().FindElement(By.XPath("li[2]/div/div/div[2]/h3/a")).Click();

                Thread.Sleep(1000);
                driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));

                var urlToCopy = driver.Url;

                #endregion

                Thread.Sleep(3000);

                #region clipconverter.cc elements

                try
                {
                    driver.Navigate().GoToUrl("http://www.clipconverter.cc/");
                    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));

                    IWebElement mediaUrl = driver.FindElement(By.XPath(".//*[@id='mediaurl']"));
                    mediaUrl.Clear();
                    mediaUrl.SendKeys(urlToCopy);

                    IWebElement continueButton = driver.FindElement(By.XPath(".//*[@id='submiturl']"));
                    continueButton.Click();

                    Thread.Sleep(1000);
                    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));

                    IWebElement mp3Option = driver.FindElement(By.XPath(".//*[@id='audiooptions']/label[1]/span"));
                    mp3Option.Click();

                    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
                    wait.Until(ExpectedConditions.ElementIsVisible(By.XPath(".//*[@id='submitconvert']/input")));

                    IWebElement startConversion = driver.FindElement(By.XPath(".//*[@id='submitconvert']/input"));
                    startConversion.Click();


                    wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
                    wait.Until(ExpectedConditions.ElementIsVisible(By.XPath(".//*[@id='downloadbutton']/span")));

                    IWebElement downloadButton = driver.FindElement(By.XPath(".//*[@id='downloadbutton']/span"));
                    downloadButton.Click();
                }
                catch (Exception ex )
                {

                    driver.Navigate().GoToUrl("https://www.youtube.com/");
                    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));

                    youtubeSearchBox = driver.FindElement(By.XPath(".//*[@id='masthead-search-term']"));
                    youtubeSearchBox.Clear();
                    youtubeSearchBo*****ndKeys(line);

                    youtubeSearchbutton = driver.FindElement(By.XPath(".//*[@id='search-btn']"));
                    youtubeSearchbutton.Click();

                    Thread.Sleep(1000);
                    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));
                    Thread.Sleep(1000);

                   testy = driver.FindElements(By.ClassName("item-section"));
                    Thread.Sleep(1000);
                    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));
                    testy.FirstOrDefault().FindElement(By.XPath("li[3]/div/div/div[2]/h3/a")).Click();

                    Thread.Sleep(1000);
                    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));

                    urlToCopy = driver.Url;

                    driver.Navigate().GoToUrl("http://www.clipconverter.cc/");
                    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));

                    IWebElement mediaUrl = driver.FindElement(By.XPath(".//*[@id='mediaurl']"));
                    mediaUrl.Clear();
                    mediaUrl.SendKeys(urlToCopy);

                    IWebElement continueButton = driver.FindElement(By.XPath(".//*[@id='submiturl']"));
                    continueButton.Click();

                    Thread.Sleep(1000);
                    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));

                    IWebElement mp3Option = driver.FindElement(By.XPath(".//*[@id='audiooptions']/label[1]/span"));
                    mp3Option.Click();

                    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
                    wait.Until(ExpectedConditions.ElementIsVisible(By.XPath(".//*[@id='submitconvert']/input")));

                    IWebElement startConversion = driver.FindElement(By.XPath(".//*[@id='submitconvert']/input"));
                    startConversion.Click();


                    wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
                    wait.Until(ExpectedConditions.ElementIsVisible(By.XPath(".//*[@id='downloadbutton']/span")));

                    IWebElement downloadButton = driver.FindElement(By.XPath(".//*[@id='downloadbutton']/span"));
                    downloadButton.Click();

                    Thread.Sleep(3000);
                }

                

                #endregion

                Thread.Sleep(250);
            }
        }
    }
}
Please note, that the converter that I use I do not represent nor do I endorse it. If there is any issues with it, please remove it (However this will break the xpaths which in turn will break the downloading part of the program).



I can include the full program if anyone is interested as well (zipped up, however some of the nugget packages may be out of date in it).

Hope this helps someone out there,
Enjoy

- VolkGoHAM

- - - Updated - - -

Also, for those interested in Selenium, here is what it is: seleniumhq. org (It is a webbrowser Automation tool).
There are some libraries to download audio tracks or videos from youtube. Why do you use a framework to do it manually rather of a framework to do it automatically?
At the time I wrote this, I was trying to build something quick (I was going on a 16 hour flight, and only had 1 day to make a program + download all of it). I didn't have time to look into API's and converting the responses so I instead build this. Yes, it is manual (semi) however for a simple downloader that I will use once or twice every few months I figure it's ok. I may eventually look into using an API but it's alot of work in something i'm not that interested in doing (the downloader really). One thing that I am interested in trying however is splitting this up into multiple threads and doing multiple downloads at once. I know very basic threading mechanics but I still have alot to learn on the subject.

This is more for a learning piece and trying to find the power in automation tools especially web-automation rather then an advanced/intricate piece of software.
No api no party
Selenium
Very nice POC program. But as you stated, since you only use it twice a month it's not realy worth it to go fish out the API of youtube.
Selenium is love, Selenium is life

However I would have changed this around;
Code:
IWebElement youtubeSearchbutton = driver.FindElement(By.XPath(".//*[@id='search-btn']"));
            youtubeSearchbutton.Click();

To
Code:
driver.FindElement(By.XPath(".//*[@id='search-btn']")).Click(); //ytSearchBtn
Also it's good practice to not use hard-coded sleeps, a better way of handling page loading would be
Code:
WebDriverWait wait = new WebDriverWait(driver, 30);
  wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("locator")));
Keep up the good work

Ps.
If you want to make your finsihed product look more professional I suggest looking into the headless-browser PhantomJS
Consider using GitHub for your code. Also, a webkit is too resource intensive for such a simple task. A webrequest will do just fine.
Posts 16 of 6 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?