Unable to click button using selenium for specific site - python

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
def main(driver):
driver.get("https://masscannabiscontrol.com/product-catalog/")
try:
element = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "button.btn"))
).click()
finally:
driver.quit()
if __name__ == "__main__":
driver = webdriver.Firefox()
main(driver)
I still keep getting timeout Exception. what could be the reason as am trying to click on I'm 21 Or Older

def main(driver):
driver.get("https://masscannabiscontrol.com/product-catalog/")
WebDriverWait(driver, 20).until(
EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe"))
)
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn"))
)
driver.execute_script(
"arguments[0].scrollIntoView({'inline':'center','block':'center'})", element)
element.click()
if __name__ == "__main__":
driver = webdriver.Firefox(desired_capabilities=firefox_capabilities)
main(driver)
The button is inside an iframe you have to switch to it first.
make sure to switch back to default content to interact again with elements outside of iframe
driver.switch_to.default_content()

This works on Chrome, not sure about Firefox
I took out the try/finally clause just to keep the window open to make sure it works
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
def main(driver):
driver.get("https://masscannabiscontrol.com/product-catalog/")
iframe = driver.find_element_by_xpath("//iframe[#src='https://catalog.metrc.com/']")
driver.switch_to.frame(iframe)
element = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "button.btn"))
).click()
driver.switch_to.default_content()
if __name__ == "__main__":
driver = webdriver.Chrome()
main(driver)
As PDHide mentioned, you need to get into the iframe first before proceeding. Also switch out of it once you are done using driver.switch_to.default_content()
EDIT: PDHide solution works fine for me in Chrome as well. His is actually a more robust solution than mine. It could be that you aren't noticing it working because the window is closing right away. Or maybe it's a weird FireFox thing

Related

Why is Selenium not finding an element

I wrote this short programm to login in to my postfield:
import time
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.web.de/')
time.sleep(2)
frame = driver.find_element_by_name('landingpage')
# do something with frame ...
driver.switch_to.frame(frame)
innerFrame = driver.find_element_by_tag_name("iframe")
driver.switch_to.frame(innerFrame)
driver.find_element_by_id("save-all-conditionally").click()
time.sleep(2)
driver.switch_to.default_content()
time.sleep(3)
inputemail = driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/section[1]/div/form/div[2]/div/input')
inputpwd = driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/section[1]/div/form/div[3]/div/input')
buttonsend = driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/section[1]/div/form/button')
inputemail.send_keys('xxx#web.de')
inputpwd.send_keys('xxx')
buttonsend.click()
time.sleep(3)
frame2 = driver.find_element_by_name('home')
driver.switch_to.frame(frame2)
linkwrite = driver.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[2]/div[1]/div[6]/div[1]/ul/li/section/div[3]/div/div[1]/a')
linkwrite.click()
This part is working fine with the iframes there. My next goal was then to fill out an input field. The Code of the page which opened after the sign in progress is the one on the picture: https://www.transfernow.net/dl/20210919Porfd5N7
But the Code for filling:
frame3 = driver.find_element_by_xpath('...')
driver.switch_to.frame(frame3)
fillin = driver.find_element_by_xpath('/html/body/div[3]/div[3]/div[3]/div[1]/div[1]/div/form/div[2]/div[1]/div[2]/div[1]/div[1]/div[2]/div/div/ul/li/input')
fillin.send_keys('hello')
has resulted in:
"Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/nav/div[2]/div[1]/div[2]/a[1]"}"
Where's my mistake?
Please help me!
Few things
There are nested iframe, first one is iframe[name='landingpage'] (located by css selector) second one is iframe[sandbox*='allow-popups'][style^='display'] and then you can click on Zustimmen und weiter button.
The xpath that you are using is absolute, try using relative xpath, if possible switch to css_selector.
Use Explicit waits.
Code :-
driver = webdriver.Chrome(driver_path)
driver.maximize_window()
driver.implicitly_wait(30)
wait = WebDriverWait(driver, 20)
driver.get("https://web.de/consent-management/")
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[name='landingpage']")))
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[sandbox*='allow-popups'][style^='display']")))
wait.until(EC.element_to_be_clickable((By.ID, "save-all-conditionally"))).click()
driver.switch_to.default_content()
inputemail = wait.until(EC.element_to_be_clickable((By.ID, "freemailLoginUsername")))
inputpwd = wait.until(EC.element_to_be_clickable((By.ID, "freemailLoginPassword")))
buttonsend = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Login']")))
inputemail.send_keys('xxx#web.de')
inputpwd.send_keys('xxx')
buttonsend.click()
time.sleep(3)
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Additionally you can use the below code :
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.pos-input input"))).send_keys('WEB.DE E-Mail-Adresse')
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.pos-input input[name^='password']"))).send_keys('password here')
to fill details on Bitte erneut einloggen page.

Parsing a dynamically loaded webpage with Selenium

I'm trying to parse https://www.flashscore.com/football/albania/ using Selenium in Python, but my webdriver often doesn't wait for the scores to finish loading.
Here's the code:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.get("https://www.flashscore.com/football/albania/")
try:
WebDriverWait(driver, 100).until(
lambda s: s.execute_script("return jQuery.active == 0"))
print(driver.page_source)
finally:
driver.quit()
Occasionally, this will print out source code for a flashscore page with a blank table (i.e. the driver does not wait for the scores to finish loading). I suspect that this is because some of the live scores on the page are dynamically loaded. Is there any way to improve my wait condition?
There's an accept cookies button, so we have to click on that first.
I am using Explicit waits, first presence of table and then visibility of it's main body.
Code :
driver.maximize_window()
driver.implicitly_wait(30)
wait = WebDriverWait(driver, 30)
driver.get("https://www.flashscore.com/football/albania/")
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button#onetrust-accept-btn-handler"))).click()
try:
wait.until(EC.presence_of_element_located((By.ID, "live-table")))
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "section.event")))
print(driver.page_source)
finally:
driver.quit()
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Output is certainly to long, so I would be able to post it here because stackoverflow won't allow me to do so.

Why is this selenium code not working always?

Why does this works only sometimes? Sometimes it navigates easily and sometimes it gets stuck after selecting a category. I want to click the category button and select notebook then the series button and click "acer one" and then the first model from model menu. But somehow it gets stuck sometimes after category and sometimes after series.
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.support.select import Select
import time
import urllib.request
PATH = r"D:\Py\Selenium\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get('https://www.acer.com/ac/en/GB/content/support')
driver.execute_script("window.scrollTo(0, document.body.scrollHeight/5);")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[7]/div[3]/div/div[3]/div/div[1]/a"))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[7]/div[3]/div/div[3]/div/div[1]/ul/li[1]/a"))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[7]/div[3]/div/div[3]/div/div[2]/a"))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[7]/div[3]/div/div[3]/div/div[2]/ul/li[2]"))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[7]/div[3]/div/div[3]/div/div[3]/a"))).click()
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"/html/body/div[7]/div[3]/div/div[3]/div/div[3]/ul/li[1]"))).click()
src = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,"/html/body/div[7]/div[2]/div/div/div[1]/img"))).get_attribute("src")
urllib.request.urlretrieve(str(src),"img.png")
time.sleep(2)
driver.quit()
# search.send_keys("m")
I'm really not sure why your code is failing, but i have tried this code which i ran multiple times and it is not failing. Please give it a try and do let me know if you have any issues running this script. Please find the code below -
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
import time
import urllib.request
driver = webdriver.Chrome()
driver.get('https://www.acer.com/ac/en/GB/content/support')
wait = WebDriverWait(driver, 30)
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(text(),'Category')]"))).click()
wait.until(EC.element_to_be_clickable(
(By.XPATH, "//a[contains(text(),'Category')]/following-sibling::ul/li/a[text()='Notebook']"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(text(),'Series')]"))).click()
wait.until(EC.element_to_be_clickable(
(By.XPATH, "//a[contains(text(),'Series')]/following-sibling::ul/li/a[text()='Acer One']"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(text(),'Model')]"))).click()
wait.until(EC.element_to_be_clickable(
(By.XPATH, "//a[contains(text(),'Model')]/following-sibling::ul/li[1]"))).click()
src = wait.until(
EC.element_to_be_clickable((By.XPATH, "/html/body/div[7]/div[2]/div/div/div[1]/img"))).get_attribute("src")
urllib.request.urlretrieve(str(src), "img.png")
time.sleep(2)
driver.quit()
I have slightly modified your code. Thank You..!

find the URL after button click from the website using selenium python

Every Button of the website may contain the link, for the below website how to find out URL appears in next tab.
wants to print and scrape the URL after the button click
am using firefox web driver
driver.get("https://www.dove.com/us/en/skin-care/body-lotion/cream-oil-intensive-body-lotion.html")
driver.find_element_by_xpath("//span[contains(text(),'Ingredients')]").click()
time.sleep(3)
driver.find_element_by_xpath("//button[contains(text(),'Go to SmartLabelâ„¢')]").click()
This should be easy, just use driver.current_url. So with your code you could try
driver.get("https://www.dove.com/us/en/skin-care/body-lotion/cream-oil-intensive-body-lotion.html")
driver.find_element_by_xpath("//span[contains(text(),'Ingredients')]").click()
time.sleep(3)
driver.find_element_by_xpath("//button[contains(text(),'Go to SmartLabelâ„¢')]").click()
time.sleep(5)
driver.switch_to.window(driver.window_handles[1])
print(driver.current_url)
I saw few problems:
1 Waits. Get rid of time.sleep(). Replace it with explicit/implicit waits. I observed that these elements are the last that are loaded on the page: picture[class='loaded']. So, I added wait for them.
2 To switch between tabs use: driver.switch_to.window(driver.window_handles[1]), driver.switch_to.window(driver.window_handles[0]) - to switch to initial tab.
Solution for Chrome
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')
# driver.implicitly_wait(10)
driver.get("https://www.dove.com/us/en/skin-care/body-lotion/cream-oil-intensive-body-lotion.html")
wait = WebDriverWait(driver, 30)
wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "picture[class='loaded']")))
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".collapsed>a[title='Ingredients']")))
driver.find_element_by_css_selector(".collapsed>a[title='Ingredients']").click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Go to SmartLabel')]")))
driver.find_element_by_xpath("//button[contains(text(),'Go to SmartLabel')]").click()
driver.switch_to.window(driver.window_handles[1])
print(driver.current_url)
driver.close()
driver.switch_to.window(driver.window_handles[0])
print(driver.current_url)
Output:
https://smartlabel.unileverusa.com/011111375512-0001-en-US/index.html
https://www.dove.com/us/en/skin-care/body-lotion/cream-oil-intensive-body-lotion.html
For Firefox you'll need to wait for at least one element on the second page, otherwise the output will not give you expected link:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("https://www.dove.com/us/en/skin-care/body-lotion/cream-oil-intensive-body-lotion.html")
wait = WebDriverWait(driver, 30)
wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "picture[class='loaded']")))
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".collapsed>a[title='Ingredients']")))
driver.find_element_by_css_selector(".collapsed>a[title='Ingredients']").click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Go to SmartLabel')]")))
driver.find_element_by_xpath("//button[contains(text(),'Go to SmartLabel')]").click()
driver.switch_to.window(driver.window_handles[1])
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".container-fluid.content-section")))
print(driver.current_url)
driver.close()
driver.switch_to.window(driver.window_handles[0])
print(driver.current_url)
P.S. If you are looking for a way to find links by attribute names, there is no way because this button does not have such. The link is generated.

Python Selenium Xpath from firebug not found

I am trying to login to the ESPN website using selenium. Here is my code thus far
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
driver = webdriver.Firefox()
driver.maximize_window()
url = "http://www.espn.com/fantasy/"
driver.get(url)
login_button = driver.find_element_by_xpath("/html/body/div[6]/section/section/div/section[1]/div/div[1]/div[2]/a[2]")
login_button.click()
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div/div/section/section/form/section/div[1]/div/label/span[2]/input")))
except:
driver.quit()
Basically, there are 2 steps, first I have to click the login button and then I have to fill in the form. Currently, I am clicking the login button and the form is popping up but then I can't find the form. I have been using firebug to get the xpath as suggested in other SO questions. I don't really know much about selenium so I am not sure where to look
Try to use
driver.switch_to_frame('disneyid-iframe')
# handle authorization pop-up
driver.switch_to_default_content() # if required
This works for me, switching to the iframe first. Note that you will need to switch back out of the iframe after entering the credentials.
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
driver = webdriver.Firefox()
driver.maximize_window()
url = "http://www.espn.com/fantasy/"
driver.get(url)
login_button = driver.find_element_by_xpath("/html/body/div[6]/section/section/div/section[1]/div/div[1]/div[2]/a[2]")
login_button.click()
iframe = driver.find_element_by_id("disneyid-iframe")
driver.switch_to.frame(iframe)
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div/div/section/section/form/section/div[1]/div/label/span[2]/input")))
element.send_keys("my username")
import time
time.sleep(100)
finally:
driver.quit()

Categories

Resources