Could you please help me with one issue? I have got a problem with Selenium and popup windows with agreements on youtube.
When first window is jumped - Selenium close this window, but if I want to close second window/frame, selenium doesn't work. Could you please help?
The part of code attached below:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from time import sleep
class YoutubeSearcher:
def __init__(self, search):
self.search = search
def open_url(self) -> None:
driver = webdriver.Chrome()
driver.get('https://www.youtube.com/')
try:
WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.XPATH, '/html/body/ytd-app/ytd-popup-container/paper-dialog/yt-upsell-dialog-renderer/div/div[3]/div[1]/yt-button-renderer/a/paper-button/yt-formatted-string'))).click()
except:
print("no alert to accept")
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[#id="yDmH0d"]/c-wiz/div[2]/div/div/div/div/div[2]/form'))).click()
search = driver.find_element_by_id("search")
search.clear()
search.send_keys(self.search)
submit_button = driver.find_element_by_id("search-icon-legacy")
submit_button.click()
From the code you have share these are my observations :
First popup.
WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.XPATH, '/html/body/ytd-app/ytd-popup-container/paper-dialog/yt-upsell-dialog-renderer/div/div[3]/div[1]/yt-button-renderer/a/paper-button/yt-formatted-string'))).click()
Second popup.
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="yDmH0d"]/c-wiz/div[2]/div/div/div/div/div[2]/form'))).click()
Suggestion :
Check the xpath once if they are correct or are there multiple locators which are being returned.
Add apprropriate waits : like isVisible,clickable for both the locator popup.
Using basic if else you can make the conditions work (no specific need of try except).
After one popup is closed check if the next popup is visible or not.
This is the code that finally works. A switching frame is needed for the second pop up. It's lame, I know but it works.
Hope it helps. Good luck.
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from time import sleep
driver = webdriver.Chrome('C:\Webdrivers\chromedriver.exe')
driver.maximize_window()
driver.get('https://www.youtube.com')
WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.XPATH,
'/html/body/ytd-app/ytd-popup-container/paper-dialog/yt-upsell-dialog-renderer/div/div[3]/div[1]/yt-button-renderer/a/paper-button/yt-formatted-string'))).click()
driver.switch_to.frame(0)
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,"/html/body/div/c-wiz/div[2]/div/div/div/div/div[2]/form/div/span/span"))).click()
Related
I'm using selenium 4 with python to automate webpage.
Click() method is not working.
Able to click a button using submit() method only if the path has type=submit, but couldnt able to select a link using click method. Please help if anyone knows alternative option for click() method to click a link.
The following is the code:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
s = Service("C:/Program Files/webdriver/Chrome Driver/chromedriver.exe")
driver = webdriver.Chrome(service=s)
driver.get("https://www.sololearn.com/users/login")
time.sleep(2)
#driver.find_element(By.CLASS_NAME, "sl-login-login-form").send_keys(Keys.ENTER)
#---click here fails--------
driver.find_element(By.CLASS_NAME, "sl-login-login-form").click()
#---click here fails
#driver.find_element(By.CLASS_NAME, "sl-login-login-form").submit()
#login.click()
time.sleep(5)
driver.quit()
**Also i have tried with the below code but still it is not working:**
driver.find_element(By.CLASS_NAME, "sl-login-login-form").send_keys(Keys.ENTER)
driver.find_element(By.CLASS_NAME, "sl-login-login-form").submit()
login.click()
Try the below
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CLASS_NAME, "CLASSNAME")))
element.click();
OR
element = driver.find_element(By.CLASS_NAME, "className")
driver.execute_script("arguments[0].click();", element)
Do not forget to import
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import org.openqa.selenium.JavascriptExecutor
I am trying to get the review of a certain product but it returns an error.
My code:
import selenium
from selenium import webdriver
chrome_path = r"C:\Users\AV\AppData\Local\Programs\Python\Python39\Scripts\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get("https://oldnavy.gapcanada.ca/browse/product.do?pid=647076053&cid=1180630&pcid=26190&vid=1&nav=meganav%3AWomen%3ADeals%3ASale&grid=pds_0_1034_1#pdp-page-content")
driver.execute_script("window.scrollTo(0, 1000)")
import time
from time import sleep
sleep(5)
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.promoDrawer__handlebar__icon"))).click()
review = driver.find_elements_by_class_name("pr-rd-description-text")
for post in review:
print(post.text)
driver.find_element_by_xpath('//*[#id="pr-review-display"]/footer/div/div/a').click()
review2 = driver.find_elements_by_class_name("pr-rd-description-text")
for post in review2:
print(post.text)
It returns: selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
Can you please tell me what should I do?
The button is really hard to click.
I guess it could be achieved by adding some more waits and moving with ActionChains class methods.
I could click it with Javascript code with no problems.
What it does:
1 Scrolls to the Next button
2 Clicks it.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')
driver.get(
"https://oldnavy.gapcanada.ca/browse/product.do?pid=647076053&cid=1180630&pcid=26190&vid=1&nav=meganav%3AWomen%3ADeals%3ASale&grid=pds_0_1034_1#pdp-page-content")
driver.execute_script("window.scrollTo(0, 1000)")
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.promoDrawer__handlebar__icon"))).click()
wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, ".pr-rd-description-text")))
review = driver.find_elements_by_css_selector(".pr-rd-description-text")
for post in review:
print(post.text)
# wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".pr-rd-pagination-btn"))).click()
element = driver.find_element_by_css_selector(".pr-rd-pagination-btn")
# actions = ActionChains(driver)
# actions.move_to_element(element).click().perform()
driver.execute_script("arguments[0].scrollIntoView();", element) # Scrolls to the button
driver.execute_script("arguments[0].click();", element) # Clicks it
print("clicked next")
I also rearranged your code, moved imports to the beginning of the file, got rid of unpredictable time.sleep() and used more reliable css locators. However, your locator should also work.
I left the options I tried commented out.
That element is weird. Even when I scroll into view, use actions to click it, or execute javascript to click, it doesn't work. What I would suggest is just grabbing the href attribute from the element and going to that URL, using something like this:
driver.get(driver.find_element_by_xpath('//*[#id="pr-review-display"]/footer/div/div/a').get_attribute('href'))
I am trying to do a tutorial and learn Selenium in python however i cant seem to get Selenium to click the "Add To Cart" button using either find_element_by_class or find_element_by_XPATH. The problem is to check if the item is out of stock, and if it is out of stock then to refresh the webpage and restart the script. If the item is in stock then it should click "Add To Cart"
I am using:
Python v3.9
Chrome v87
This is the URL i am practicing on:
https://www.currys.co.uk/gbuk/tv-and-home-entertainment/televisions/televisions/samsung-ue75tu7020kxxu-75-smart-4k-ultra-hd-hdr-led-tv-10213562-pdt.html
And this is my current code for the clicking:
# Selenium Tutorial #1
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Chrome(r"C:\Users\Ste1337\Desktop\chromedriver\chromedriver.exe")
driver.get("https://www.currys.co.uk/gbuk/tv-and-home-entertainment/televisions/televisions/samsung-ue75tu7020kxxu-75-smart-4k-ultra-hd-hdr-led-tv-10213562-pdt.html")
#search = driver.find_element_by_id(ContentPlaceHolder1_NotifyBtn)
link = driver.find_element_by_id("onetrust-accept-btn-handler")
link.click
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "onetrust-accept-btn-handler"))
)
element.click()
except Exception:
pass
driver.implicitly_wait(2)
try:
element = WebDriverWait(driver, 1).until(
EC.presence_of_element_located((By.XPATH, "email-desktop"))
)
time.sleep(1)
browser.refresh()
except:
driver.find_element_by_class_name("Button__StyledButton-bvTPUF hZIOeU Button-jyKNMA GZkwS")
link.click()
You cannot pass multiple classes to find_element_by_class_name. Instead use driver.find_element_by_css_selector or xpath.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Chrome(r"C:\Users\Frank\Documents\Python Scripts\chromedriver_win32\chromedriver.exe")
driver.get("https://www.currys.co.uk/gbuk/tv-and-home-entertainment/televisions/televisions/samsung-ue75tu7020kxxu-75-smart-4k-ultra-hd-hdr-led-tv-10213562-pdt.html")
#search = driver.find_element_by_id(ContentPlaceHolder1_NotifyBtn)
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "onetrust-accept-btn-handler"))
)
element.click()
except Exception:
pass
driver.implicitly_wait(2)
try:
element = WebDriverWait(driver, 1).until(
EC.presence_of_element_located((By.XPATH, "email-desktop"))
)
time.sleep(5)
driver.refresh()
except:
button = driver.find_element_by_css_selector("button.Button__StyledButton-bvTPUF.hZIOeU.Button-jyKNMA.GZkwS")
Next, if you would call button.is_displayed() it will return False, because it is a hidden element. This means you cannot interact with it using button.click(). Instead, you can use javascript to click the button.
driver.execute_script("arguments[0].click();", button)
I am trying to scrape some google data but I first want to click the 'I agree' button that google pops up. This is the script I use to do that:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
search_question = input("Ask a question: ")
driver = webdriver.Chrome("*Your Webdriver location*")
driver.wait = WebDriverWait(driver, 5)
driver.get("https://google.com")
time.sleep(1)
agree = driver.wait.until(EC.presence_of_element_located((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
# time.sleep(0.2)
search = driver.find_element_by_class_name("gLFyf")
search.send_keys(search_question)
search.send_keys(Keys.ENTER)
The problem is selenium doesn't seem to locate the button and therefore I get a timeout error. (I have tried also with find_element_by_xpath and still not working).
If you scroll up in the devtools inspector you'll notice that your element is within an iframe:
You need to switch to that frame first, click your button then switch back to the default content (the main page)
driver.get("https://google.com")
#active the iframe and click the agree button
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe")))
agree = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
#back to the main page
driver.switch_to_default_content()
That works for me.
FYI - There's only 1 iframe on the page, that's why the xpath //iframe works. If there were multiple you'd need to identify it with higher accuracy.
If you already have been agreed,then agree button would not appear. That why it is not be able to find given XPath.
Try this:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
search_question = input("Ask a question: ")
driver = webdriver.Chrome(".\chromedriver.exe")
driver.wait = WebDriverWait(driver, 5)
driver.get("https://google.com")
time.sleep(3)
# agree = driver.wait.until(EC.presence_of_element_located((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
# agree.click()
# time.sleep(0.2)
search = driver.find_element_by_class_name("gLFyf")
search.send_keys(search_question)
search.send_keys(Keys.ENTER)
Managed to get it working.
Seems like one of the few elements that are interactive in the popup when you first load the site is the language dropdown, which I found by class name.
Then the Agree button is detectable and you can find it by class too.
driver.get("https://www.google.com")
driver.maximize_window()
time.sleep(2)
#finds+clicks language dropdown, interaction unhides the rest of the popup html
driver.find_element_by_class_name('tHlp8d').click()
time.sleep(2)
#finds+clicks the agree button now that it has become visible
driver.find_element_by_id('L2AGLb').click()
you should now have the standard searchbar etc
i had some problems with clicking pop-ups and the problem turned out to be with that click().
im not sure that it might be the same issue with urs or not but try changing ur click to this :
agree = driver.find_element_by_xpath('//*[#id="introAgreeButton"]/span/span')
driver.execute_script("arguments[0].click();", agree)
The problem was that it didn't change frames here is the soulution code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome('C:\\Users\\gassp\\OneDrive\\Namizje\\Python.projects\\chromedriver.exe')
url = 'https://www.google.com/maps/'
driver.get(url)
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//*[#id="consent-bump"]/div/div[1]/iframe')))
agree = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
#back to the main page
driver.switch_to_default_content()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="searchboxinput"]'))).send_keys('gostilne')
driver.submit()
I need a script which logs me in to github and presses a Read the guide button. I've got it to log in but after it's done it does not work any more. Please help.
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('https://github.com/session')
login_area = browser.find_element_by_name('login')
login_area.send_keys('maximmashkov')
login_area = browser.find_element_by_id('password')
login_area.send_keys('12345')
submit_button = browser.find_element_by_name('commit')
submit_button.click()
To click() on the element with text as Read the guide you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following solutions:
Using LINK_TEXT:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Read the guide"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.btn.btn-primary[href='https://guides.github.com/activities/hello-world/']"))).click()
Using XPATH:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#href='https://guides.github.com/activities/hello-world/' and text()='Read the guide']"))).click()
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
Most probably your script fails to wait for the "Read the guide" button to appear, consider using Explicit Wait so Selenium could wait for a defined period of time for the element to appear in DOM
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
#initialize your browser here
login_area = browser.find_element_by_name('login')
login_area.send_keys('maximmashkov')
login_area = browser.find_element_by_id('password')
login_area.send_keys('12345')
submit_button = browser.find_element_by_name('commit')
submit_button.click()
submit_button = browser.find_element_by_name('commit')
submit_button.click()
read_the_guide = element = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.LINK_TEXT, "Read the guide")))
read_the_guide.click()
browser.quit()
More information:
How to use Selenium to test web applications using AJAX technology
How to wait for elements in Python Selenium WebDriver
The solution was posted in the question and moved here:
You only have to put a little time.sleep() delay. One second is enough