how to incease sleep time of selenium until song complete - python

how can I increase this sleep time to until my song finished. I am working on a voice assistance.
def play(self,query):
self.query=query
self.driver.get(url="https://www.youtube.com/results?search_query=" + query)
video=self.driver.find_element_by_xpath('//*[#id="video-title"]/yt-formatted-string')
video.click()
time.sleep(50)

Suggest to set sleep duration to duration of the video which you can retrieve using this

When the single YouTube video is finished Play Next and Cancel buttons appearing.
So you can use expected conditions to wait until that element is appearing. Like this:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 20000)
wait.until(EC.visibility_of_element_located((By.XPATH, "//a[#class='ytp-autonav-endscreen-upnext-button ytp-autonav-endscreen-upnext-play-button']")))

Related

Play YouTube video until finished

I am using a Selenium to code python script to search and play a YouTube video.
This is my code:
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Defining video name
video_name = "4k art"
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.maximize_window()
wait = WebDriverWait(driver, 3)
presence = EC.presence_of_element_located
visible = EC.visibility_of_element_located
# Navigate to url with video being appended to search_query
driver.get('https://www.youtube.com/results?search_query={}'.format(str(video_name)))
# play the video
wait.until(visible((By.ID, "video-title")))
driver.find_element(By.ID, "video-title").click()
# Wait for video to end
So, everything works fine, but I would like to know what is the best way to have the script wait until the video is finished before finishing? I saw different ways to do so using YouTube API or using Selenium with elements appearing. Is there a preferred way to do it?
You could look for the replay button and if it comes up exit the loop
wait=WebDriverWait(driver,10)
While True:
try:
wait.until(EC.element_to_be_clickable((By.XPATH,"//button[#aria-label='Replay']")))
break
except:
pass
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
It depends on what functionality you are testing.
In case you don't care about actual GUI presentation and just wish to get indication that the video is finished and you can do it with some API - do it with API. This is much more fast and stable approach.
In case you need to test the actual video finished on the GUI - you should wait for the appropriate web element with Selenium.
In this case you can use the solution given by Arundeep

Selenium Explicit Waits for invisibility_of_element() not waiting at all

I am trying to make Selenium wait until a loader div is invisible.
These are my imports:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait, Select
from selenium.webdriver.support.ui import expected_condition as EC
I first click on a button to open a pop up window with table data in it.
action.click()
action.perform()
After clicking I have to wait until I can press a button to export this data in a file. However, the time I have to wait varies wildly. Sometimes 10 seconds sometimes a few minutes. While this section is loading a loader shows up which prevents me from clicking anywhere on the screen.
I am trying to make Selenium wait until this loader is gone. However, for some reason, the script does not wait at all. Not even the maximum time, which is passed into the explicit wait function.
time.sleep(10)
print("Waiting for button")
wait = WebDriverWait(driver, 30) # I am just testing with 30, it will be a larger value
wait.until(EC.invisibility_of_element((By.XPATH, "//div[#class='loader']")))
print("Finished Waiting for button")
driver.find_element_by_xpath("//button[#class='export']").click()
First I am making Selenium wait 10 seconds so that the loader element can actually show up, which already shows up in 1-2 seconds.
After that I use print statement to check how long the script actually wait.
The script does not wait at all. It immediately continues which then causes an error because the button is not clickable yet.
You are passing a By.locator so instead of invisibility_of_element() you must be using invisibility_of_element_located().
First to wait for the visibility and then for the invisibility of the element you need to:
First induce WebDriverWait for the visibility_of_element_located()
Then induce WebDriverWait for the invisibility_of_element as follows:
WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='loader']")))
WebDriverWait(driver, 30).until(EC.invisibility_of_element_located((By.XPATH, "//div[#class='loader']")))
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

How to close browser(ChromeDriver) on time using Python

I made a Python program that opens my Youtube playlist using Selenium and I want to close that browser when all video is watched.
(I tried using time.sleep() but the problem is Youtube ads).
So, is there any way I can close my browser automatically when all video is watched?
When the video is finished //div[#class='ytp-autonav-endscreen-button-container'] element appears so you can wait until this element appearing and then close the driver.
You can also simply locate it by the class name 'ytp-autonav-endscreen-button-container' or other buttons / elements inside it.
So after staring the video use
WebDriverWait(driver, delay).until(EC.visibility_of_element_located((By.ID, 'ytp-autonav-endscreen-button-container')))
where delay is time that will be enough to the video to finish.
Lear more about webdriver explicit wait conditions here
Don't forget to add the essential imports
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
I suggest to make in in steps.
First step:
Wait for the last video in playlist:
By text:
last_video = driver.find_element_by_css_selector("#secondary .index-message.style-scope.ytd-playlist-panel-renderer:nth-child(1)").text == "10 /10"
Or by waiting for the last element in the playlist directly:
last_video = driver.find_element_by_css_selector("#secondary #items>.style-scope.ytd-playlist-panel-renderer:last-of-type").get_attribute("selected")
Second step:
After the first condition is true, wait for this video to finish, with this locator (Replay button)
video_ends = driver.find_element_by_css_selector(".ytp-chrome-controls button[title=Replay]")
For this you'll need to import:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
And use it like this:
wait = WebDriverWait(driver, timeout_in_seconds)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#secondary .index-message.style-scope.ytd-playlist-panel-renderer:nth-child(1)").text == "10 /10")))
Timeout will depend of the length of playlist.
It is not a quick task, nobody will agree to finish it for you here.

Selenium script to detect presence of button and to click on it when it appears not working

Python/coding newb, beware!
Im writing a script to download from youtube from " https://ytmp3.cc/en13/ ". I had written a click script using pyautogui but the problem being that the download button appears anywhere betweeen 1 and 15 seconds of entering the link. So i wanted to re-code it in a Selenium window to dynamically wait until the button is visible and then continue with the click script. I have tried about 15 ways but cant get it to work
library blah :
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support.expected_conditions import presence_of_element_located
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
ways i tried to get it to work:
without waits, results in NosuchElement Exception
def check_exists():
try:
while True:
a=driver.find_element(By.LINK_TEXT, "Download")
a.click()
except NoSuchElementException:
time.sleep(10)
the syntax of this is most probably wrong
i tried a couple different variations of implicit and explicit waits but couldnt get it to work. Is there some javascript on the site linked above thats messing with my code?
in a separate .py, running
#driver.find_element(By.LINK_TEXT, "Download").click()
#either the line above or below works at finding the element, and clicking it
driver.find_element_by_link_text("Download").click()
I just need help getting the line above ^ into an explicit wait, but i dont have the language knowledge of how to do it yet. i would appreciate some help, thanks in advance!
You can use webdriver wait to wait until button is displayed. Tried the below code which works for me
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
video_path = "your_video_path"
waitTime=10
driver = webdriver.Chrome("./chromedriver.exe")
driver.get("https://ytmp3.cc/")
element = driver.find_element_by_id("input")
element.send_keys(video_path)
driver.find_element_by_id("submit").click()
try:
# wait 10 seconds before looking for element
element = WebDriverWait(driver, waitTime).until(
EC.presence_of_element_located((By.LINK_TEXT,"Download"))
)
driver.find_element_by_link_text("Download").click()
finally:
print(driver.title)
You can update your required wait time in waitTime variable in seconds so if the value is 10 selenium will wait and check for elements upto 10 seconds

How to make selenium python script to keep clicking a button?

Objective:
Run a continuous function to keep clicking a button on target url page with wait between clicks
url = "https://kingoftheclicks.com/?ref=ghost-of-a-chance"
target button = "+ Click button"
Later I will set it to target opponent "clicks - 1,000"
//*[#id="__layout"]/div/main/div[3]/div[3]/div/div[2]/div/div[2]/div[1]/div[3]/text()[2]
Need help getting this basic code to work and click button.
from selenium.webdriver.common.action_chains import ActionChains
elem = driver.find_element_by_xpath('//a#id="__layout"]/div/main/div[3]/div[3]/div/div[2]/div/div[2]/div[2]/div[2]/div[2]')
actions = ActionChains(driver)
actions.click(elem).perform()
You can use a loop to do an action over and over. For example, to print something 10 times:
for i in range(10):
print("foo")
You can also use while loops, whose syntax is something like:
while [some_condition_is_true]:
[do something]
If you need to wait between each click, you can sleep:
import time
time.sleep(0.1) #This will pause the program for 100 milliseconds
You first need a better locator! then you should use WebDriverWait.
As #Kosay suggested to use while here is an implementation:
driver.get("https://kingoftheclicks.com/?ref=ghost-of-a-chance")
WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.advance")))
driver.find_element(By.CSS_SELECTOR, "button.advance").click()
WebDriverWait(driver,30).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".fighter--challenger .fighter-btn")))
while driver.find_element(By.CSS_SELECTOR,".fighter--challenger .fighter-btn").is_displayed():
driver.find_element(By.CSS_SELECTOR, ".fighter--challenger .fighter-btn").click()
Note: I added WebDriverWait so you'll need to import it too.
Here are the imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Categories