Learn selenium Automation with Spotify | Part 2 | Python | AI Assistant

Part - 2: Learn Automation with Spotify
Basic to Advance



Question from the previous Part 


Download function()
FOR defining a function download for downloading song or album from the current browser. we will install a library name spotdl. spotdl library used to download songs and albums from Spotify you can install spotdl by doing pip install spotdl
>> spotdl
  • pip install spotdl
So to download a album or song you just need to call spotdl and provide link of song or the album so for a example i am taking this an an example
Example:  spotdl https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b

we will make 2 strings and add str1 and str_2, str1 is spotdl, and remember to give the space as you can see in the example.str2 will be the link of the song so to get current_url from the browser we do
driver.current_url
now we will make variable str and add both the strings and append it in os.system() method.
os.system() execute the command (a string) in a subshell. the command generates output and it is sent to the interpreter with a standard output stream. now we will print the statement for downloading.

Test condition : before calling a function, 1st we will redirect to a song so adding sleep for 3 sec and calling driver.get("song_url") and we will put the URL of any song for a test
so it will open the song after 3 sec and then we will call the download function to download the song after 15 sec we will close the driver so to close a driver we use 
driver.close() 
if the driver is not closed, the driver will keep running in the background and consume ram every time when a drive is called so it is important to close the driver!
  1. def download():
  2. str1 = "spotdl "
  3. str2 = driver.current_url
  4. str = str1 + str2
  5. os.system(str)
  6. print("Downloaded")
Test condition
  • login(config.username, config.password)
  • sleep(3)
  • driver.get("https://open.spotify.com/album/3GzwPyPZCyrqUTaurTaS23")
  • sleep(3)
  • sleep(3)
  • download()
  • sleep(15)
  • driver.close()

Adding a song to the playlist function()  /-  without Wait and Action chain
To add a song to a playlist we click on the 3 dots and hover to Add to playlist and we get the playlist that we have created. we will automate by adding this song to anime_song_playlist. First, we will try by just clicking the button and see what happens and further we will learn some concepts and automate this effectively 
so let's create a function name playlist
driver.find_element by XPath  and  .click to click the button
in the first part, we have covered this in more detail, click here for rewatching concepts
Part 1 -  Learn selenium Automation with Spotify

we will duplicate this three times because we need three clicks to add the
song in the playlist .three-dot is an SVG, if you directly use the XPath it will throw an error
so to click an SVG there is a method.

I just edited the end removing SVG and this worked for me
you can also try a different approach which I have explained in the image


next, we will simply get the x path of add to playlist, if you are getting errors in single quotes try using double quotes. now let's copy the x path of the anime song playlist for the test, we are commenting on the download function and calling the playlist function
Code without sleep!
  1. def playlist():
  2. # clicks on 3-dots
  3. driver.find_element(By.XPATH,'//*[@id="main"]/div/div[2]/div[3]/div[1]/div[2]/div[2]/div/div/div[2]/main/section/div[3]/div/button[2]').click()
  4. # clicks on a Add to playlist
  5. driver.find_element(By.XPATH,"//span[normalize-space()='Add to playlist']").click()
  6. # click on anime song
  7. driver.find_element(By.XPATH,"//button[@role='menuitem']//span[@dir='auto'][normalize-space()='anime song").click()
Output:
Error when you do not use sleep

We get an error because the path we provided doesnot got enough time to get search or load, to search a path it require some time for searching and loading, and here clicks are called syentaniously ,as you can see , so lets add some time by adding sleep for 2 sec each, before a click
  1. def playlist():
  2. # clicks on 3-dots
  3. driver.find_element(By.XPATH,'//*[@id="main"]/div/div[2]/div[3]/div[1]/div[2]/div[2]/div/div/div[2]/main/section/div[3]/div/button[2]').click()
  4. sleep(2)
  5. # clicks on a Add to playlist
  6. driver.find_element(By.XPATH,"//span[normalize-space()='Add to playlist']").click()
  7. sleep(2)
  8. # click on anime song
  9. driver.find_element(By.XPATH,"//button[@role='menuitem']//span[@dir='auto'][normalize-space()='anime song").click()
This works because we added sleep and there it got time to search paths and click...
we used to sleep, which is not a good practice for automation the efficient way of handling this is by using  WAITS AND ACTION CHAIN

Difference between Sleep() and Wait()


The question is what are WAITS AND ACTION CHAIN
ACTION CHAIN is Interactions such as mouse movements, and button actions. This is useful for doing more complex actions like hovering over and dragging and dropping.
lets import actionchain 
  • from selenium.webdriver import ActionChains
so we have to hover over the playlist and then click on anime song. let's create a variable name sub_menu which is equal to driver.find_element() by Xpath and give the path of XPath chain variable for action chain and put the driver
chain.move_to_element(sub-menu).performe
to perform the action chain

as we know if we do not use sleep, we face an error here instead of sleep we will use WAIT here Explicit wait which is The condition that is called with a certain frequency until the timeout of the wait is elapsed. This means that for as long as the condition returns a false value, it will keep trying and waiting. so now let's import this
one more thing we need to add with explicit wait is .. expected condition
  • from selenium.webdriver.support.wait import WebDriverWait
  • from selenium.webdriver.support import expected_conditions as EC
The explicit wait is performed until the expected condition is satisfied 
or the wait duration has elapsed wait variable which holds time 
wait until the condition element is clickable and provide the same path now let's just print  =   added to the anime playlist and you can use this anywhere you feel an error might occur  like in the login function it will wait for the login button after filling in both password and email then it will click!

Full Code : 
  1. import os
  2. from time import sleep
  3. import config
  4. from selenium import webdriver
  5. from selenium.webdriver.common.by import By
  6. from selenium.webdriver import ActionChains
  7. from selenium.webdriver.support.wait import WebDriverWait
  8. from selenium.webdriver.support import expected_conditions as EC

  9. options = webdriver.ChromeOptions()
  10. options.headless = True # if false all the stuff will load in backend
  11. driver = webdriver.Chrome('C:\PythonX\Python_Exp_yt\Spotify Automation\chromedriver.exe')

  12. # Driver path cheak your current browser first than download respectively >>
  13. # chrome://settings/help

  14. url = 'https://accounts.spotify.com/en/login?continue=https%3A%2F%2Fopen.spotify.com%2F'
  15. wait = WebDriverWait(driver,10)

  16. def login(Email, Password):
  17. driver.maximize_window()
  18. driver.get(url)

  19. driver.find_element(By.CSS_SELECTOR, "#login-username").send_keys(Email)
  20. driver.find_element(By.CSS_SELECTOR, "#login-password").send_keys(Password)

  21. wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[id='login-button'] div:nth-child(1)"))).click()


  22. # spotdl https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b

  23. def download():
  24. str1 = "spotdl "
  25. str2 = driver.current_url
  26. str = str1 + str2
  27. os.system(str)
  28. print("Downloaded")

  29. def playlist():
  30. driver.find_element(By.XPATH,'//*[@id="main"]/div/div[2]/div[3]/div[1]/div[2]/div[2]/div/div/div[2]/main/section/div[3]/div/button[2]').click()

  31. # Hover to playlist
  32. sub_menu = driver.find_element(By.XPATH, "//span[normalize-space()='Add to playlist']")
  33. chain = ActionChains(driver)
  34. chain.move_to_element(sub_menu).perform()

  35. # Add song in anime_song playlist

  36. wait.until(EC.element_to_be_clickable((By.XPATH,"//button[@role='menuitem']//span[@dir='auto'][normalize-space()='anime song']"))).click()


  37. login(config.username, config.password)
  38. sleep(3)
  39. driver.get("https://open.spotify.com/album/3GzwPyPZCyrqUTaurTaS23")
  40. sleep(3)
  41. sleep(3)
  42. #download()
  43. #playlist()
  44. sleep(15)
  45. driver.close()
 In Part - 7 we will see more topics 
Stay tuned till then :)





2 Comments

If you have any doubts, please let me know

Previous Post Next Post