How to click button in pop up window using python-selenium - python

I'm working to automate web page where i'm unable to close the pop up. I have tried to refresh/switch to pop up window, nothing worked.
Code:
from selenium import webdriver
import time
driver = webdriver.Chrome(executable_path='F:\chromedriver_win32\chromedriver.exe')
driver.get('https://www.libertymutual.com/get-a-quote')
driver.maximize_window()
driver.find_element_by_xpath(
'//*[#id="1555468516747"]/section/div[2]/section/form/div[1]/div[3]/div/div[1]').click()
time.sleep(1)
driver.find_element_by_xpath('//*[#id="zipcode-1555468516747-1555468516747"]').click()
driver.find_element_by_xpath('//*[#id="zipcode-1555468516747-1555468516747"]').send_keys('03878')
time.sleep(1)
driver.find_element_by_xpath(
'//*[#id="1555468516747"]/section/div[2]/section/form/div[2]/div[5]/div/div/button').submit()
time.sleep(5)
x=driver.find_element_by_xpath('//*[#id="discount-marketing-modal"]/header/button/svg').click()
driver.refresh()
If you want directly go to web page, https://buy.libertymutual.com/auto?city=Somersworth&jurisdiction=NH&lob=Auto&policyType=Auto&zipCode=03878

Replace last 3 lines of your code by below lines.Used action chain to click.
time.sleep(5)
ok = driver.find_element_by_xpath('//*[#id="discount-marketing-modal"]/footer/button')
ActionChains(driver).move_to_element(ok).pause(1).click(ok).perform()
x=driver.find_element_by_xpath('//*[#id="discount-marketing-modal"]/header/button/svg').click()

This is css selector for popup close button : .lm-Icon.lm-Icon-Close
But this element can't use the .click() method, the .click() method will produce this error:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted:
Use ActionChains to solve this problem.
You can try the following code:
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 import webdriver
from selenium.webdriver import ActionChains
driver = webdriver.Chrome(executable_path='F:\chromedriver_win32\chromedriver.exe')
driver.get('https://www.libertymutual.com/get-a-quote')
driver.maximize_window()
wait = WebDriverWait(driver, 20)
auto_element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[#class='quotingText']//span[contains(text(), 'Auto')]")))
auto_element.click()
zip_code = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.zipcode")))
zip_code.click()
zip_code.send_keys("03878")
driver.find_element_by_css_selector('div.buttonWrapper button').submit()
popup_close_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".lm-Icon.lm-Icon-Close")))
action = ActionChains(driver)
action.move_to_element(popup_close_btn).click(popup_close_btn).perform()
WebDriverWait better than time.sleep(..)

Related

Selenium error: element click intercepted:Other element would receive the click:

I'm trying to use Selenium to click on "show more" under "about this show" on this URL:
https://www.bandsintown.com/e/1024477910-hot-8-brass-band-at-the-howlin'-wolf?came_from=253&utm_medium=web&utm_source=city_page&utm_campaign=event
Here's my code:
#Get Event Info - expand 'read more'
try:
time.sleep(3)
readMoreEvent = driver.find_element_by_xpath("//div[#class='xXGKBimvIBU_aEdJh3EF']").click();
print("More Event Info Clicked")
except (ElementNotVisibleException, NoSuchElementException, TimeoutException):
pass
I'm getting an error:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted:
.</div> is not clickable at point (477, 9). Other element would receive the click:
Here's a photo of the div I'm trying to click:
So, it seems like something is blocking the page-click. How can I solve this issue?
I saw that there's a dialogue box that pops up which asks user to login. That could be interrupting the click.
A better approach is to:
Wait until the link is clickable
Capture the exception and use an alternative method to click on the link
This should work:
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.common.exceptions import ElementClickInterceptedException
from selenium.webdriver.chrome.options import Options
from time import sleep
options = Options()
options.add_argument("--disable-notifications")
driver = webdriver.Chrome(executable_path='D://chromedriver/100/chromedriver.exe', options=options)
wait = WebDriverWait(driver, 20)
url = "https://www.bandsintown.com/e/1024477910-hot-8-brass-band-at-the-howlin%27-wolf?came_from=253&utm_medium=web&utm_source=city_page&utm_campaign=event"
driver.get(url)
try:
showmore_link = wait.until(EC.element_to_be_clickable((By.XPATH, '//div[#class="xXGKBimvIBU_aEdJh3EF"]')))
showmore_link.click()
except ElementClickInterceptedException:
print("Trying to click on the button again")
driver.execute_script("arguments[0].click()", showmore_link)

ElementNotInteractableException: element not interactable in Selenium

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'))

Can you help me use Selenium to click Add To Cart button?

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)

Popup window on youtube - how to close with selenium

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()

Executing event and scrape using selenium

I am pretty new in selenium and I was looking forward to execute a click() button that expands a table, and after that I was looking forward to scrape the content of the expanded table.
This is what I tried:
url = 'https://www.telegraph.co.uk/markets-hub/assets/shares/'
phantomjs_path = '/usr/local/bin/phantomjs'
driver = webdriver.PhantomJS(executable_path=phantomjs_path,service_args=['--load-images=no'])
driver.get(url)
element = driver.find_element_by_xpath("//div[#class='tmg-show-more']")
html_source = driver.page_source
element.click()
driver.quit()
soup = BeautifulSoup(html_source,"html5lib")
tables=soup.find('table',class_="table-static kurser-table")
link=pd.read_html(str(tables),flavor='html5lib',thousands='.',decimal=',',header=0)
print(link)
The current output is as it follows:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotVisibleException: Message: {"errorMessage":"Element is not currently visible and may not be manipulated",
"request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"81","Content-
Type":"application/json;charset=UTF-8","Host":"127.0.0.1:58447","User-Agent":"Python http auth"},
"httpVersion":"1.1","method":"POST","post":"{\"id\": \":wdc:1556893378248\", \"sessionId\": \"f223cb80-6dae-11e9-b00b-4bb158952171\"}",
"url":"/click","urlParsed":{"anchor":"","query":"","file":"click","directory":"/","path":"/click","relative":"/click","port":"","host":"","password":"","user":"",
"userInfo":"","authority":"","protocol":"","source":"/click","queryKey":{},"chunks":["click"]},"urlOriginal":"/session/f223cb80-6dae-11e9-b00b-4bb158952171/element/:wdc:1556893378248/click"}}
Screenshot: available via screen
You would need to scroll down to let the selenium web driver knows where the element is actually present.
Code :
driver.get("https://www.telegraph.co.uk/markets-hub/assets/shares/")
wait = WebDriverWait(driver, 10)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'div.section-box.kurser-table-container')))
element = driver.find_element_by_xpath("//a[#ng-click='stocksShowMore()']")
actions = ActionChains(driver)
actions.move_to_element(element).perform()
element.click()
Imports :
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
You are getting ElementNotVisibleException means you are trying to click the element before it is visible.
Also, you are getting the page source before clicking the button. You need to get the source after clicking and loading the new data.
Try the following code before getting the page source.
wait = WebDriverWait(driver, 20)
element = wait.until(EC.element_to_be_clickable(driver.find_element_by_xpath("//div[#class='tmg-show-more']")))
element.click()
wait.until(EC.invisibility_of_element(element))
To use the WebDriverWait you need to import these
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Categories