How to click span based on text given - python

Consider this:
https://www.lanebryant.com/lace-trim-overpiece/prd-358988#color/0000006400
Click What's my size and then click get started. You'll see a drop down that has age ranges. I need to click those based on value that I have already. Consider my code:
wait.until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[2]/div/div/div/div[2]/form/tfc-accordion-group/div[2]/div/div[2]/span/div[2]/div//span[text()=" + " "+ df_temp.age + " " + "]"))).click()
df_temp['age'] has value 16-18
But it doesn't click and gives timeout exception.

First click to the dropdown to open list of options, than click on item using //div[#value="ageRange.id" and contains(.,"16 - 18")] or //div[#value="ageRange.id" and normalize-space(.)="16 - 18"] xpath:
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[aria-label="Age"]'))).click()
wait.until(EC.visibility_of_element_located((By.XPATH, '//div[#value="ageRange.id" and contains(.,"16 - 18")]'))).click()

I hope this will help you, for the detail of every step see the code comments.
import time
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
# Configure the webdriver and webdriver-wait instances
driver = webdriver.Chrome()
driver.maximize_window()
wait = WebDriverWait(driver, 10)
# Load the webpage
driver.get("https://www.lanebryant.com/lace-trim-overpiece/prd-358988#color/0000006400")
time.sleep(5)
# Open the popup
wait.until(EC.presence_of_element_located(
(By.XPATH, '//*[#id="358988"]//td/a[#class="tfc-popup-click-open"]'))).click()
time.sleep(4)
# Find the popup iframe and make driver to focus the same
popup_iframe = wait.until(EC.visibility_of_element_located(
(By.XPATH, '//div[contains(#aria-label, "True Fit")]/iframe')))
driver.switch_to.frame(popup_iframe)
# To switch the focus back to the main content window,
# execute: driver.switch_to.default_content()
# Click the get-started button
wait.until(EC.presence_of_element_located(
(By.XPATH, '//*[contains(#class, "tfc-cfg-nav-button")]/button'))).click()
# Find the age dropdown
age_dropdown = wait.until(EC.presence_of_element_located(
(By.XPATH, '//*[#class="tfc-select-custom"]/button')))
# Let's say you want to select age group:
# 35-44, so minAge here is 35
min_age = 35
# Activate the age dropdown and select and click the desired option
age_dropdown.click()
age_option = wait.until(
EC.visibility_of_element_located(
(By.XPATH, '//*[#class="tfc-select-custom"]//div[#class="tfc-select-body"]/div/span[contains(text(),%s)]' % (min_age))))
age_option.click()
time.sleep(20)

Related

How to click on links with no names with selenium Python

I'm trying to click on all the links on a web page after clicking on the dates (https://www.eduqas.co.uk/qualifications/computer-science-as-a-level/#tab_pastpapers) but the links don't have unique class names and only have a tag name "a" but multiple other elements have the same tag name. How can I click on the links
Here is the current code, it clicks on the dates but as I said I can't click on the links:
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
PATH = "C:\Program Files (x86)\chromedriver.exe" # path of chrome driver
driver = webdriver.Chrome(PATH) # accesses the chrome driver
driver.get("https://www.eduqas.co.uk/qualifications/computer-science-as-a-level/#tab_pastpapers") # website
driver.maximize_window()
driver.implicitly_wait(3)
driver.execute_script("window.scrollTo(0, 540)")
sleep(3) # Giving time to fully load the content
elements = driver.find_elements(By.CSS_SELECTOR, ".css-13punl2")
driver.find_element(By.ID, 'accept-cookies').click() # Closes the cookies prompt
for x in elements:
if x.text == 'GCSE':
continue
x.click()
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # this scrolls the page to the bottom
sleep(1) # This sleep is necessary to give time to finish scrolling
print(len(elements))
Image of links
I think you are trying this:
# Needed libs
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
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Chrome()
driver.get('https://www.eduqas.co.uk/qualifications/computer-science-as-a-level/#tab_pastpapers')
driver.maximize_window()
actions = ActionChains(driver)
# We get how many dates (year) fields we have
dates_count = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.XPATH, "//div[#id='pastpapers_content']//button[#class='css-13punl2']/..")))
driver.find_element(By.ID, 'accept-cookies').click()
# We do scroll to the year element and we click every year
for i in range(1, len(dates_count)+1):
date = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, f"(//div[#id='pastpapers_content']//button[#class='css-13punl2']/..)[1]")))
driver.execute_script("arguments[0].scrollIntoView();", date)
time.sleep(0.3)
date.click()
time.sleep(0.3)
# For every year we get all the links
links = date = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.XPATH, f"(//div[#class='css-1301qtx'])[{i}]//a")))
# We do scroll to the link element and we click every link
for link in links:
driver.execute_script("arguments[0].scrollIntoView();", link)
time.sleep(0.3)
link.click()
driver.switch_to.window(driver.window_handles[0])
This open every singlle link in the page.
I hope the comments into the code help to understand what the code does
The main reason for using XPath is when you don’t have a suitable id or name attribute for the element you wish to locate. You can use XPath to either locate the element in absolute terms (not advised) or relative to an element that does have an id or name attribute. XPath locators can also be used to specify elements via attributes other than id and name.
Find the elements:
elem = driver.find_element(By.XPATH, "/html/body/form[1]")
Get XPath:
Go to the inspect window
Select the desired element and right-click on it
In the dropdown click on copy tab, then on copy XPath
Hope this helps.Happy Coding:)

Element not clickable, ElementClickInterceptedException in Selenium

A similar question has been asked many times, and I have gone over many of them, such as Debugging "Element is not clickable at point" error
, Selenium Webdriver - element not clickable error in firefox, ElementClickInterceptedException: Message: element click intercepted:
but haven't been able to solve my problem.
I want to select a subset of car brands from the websites search dropdown menu. Usually I would do it via Selenium's Select, but that doesn't do the trick here.
Here's my code.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.proxy import Proxy, ProxyType
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
ser = Service(executable_path= r'D:\chromedriver.exe')
#Note I have omitted the options that I use (proxy and header).
driver = webdriver.Chrome(service = ser)
driver.get("https://www.autotalli.com/")
time.sleep(5)
# Accepting cookies
driver.find_element(by = By.XPATH, value = "//button[contains(text(),'Asetuks')]").click()
time.sleep(5)
driver.find_element(by = By.XPATH, value = "//button[contains(text(),'Tallenna')]").click()
driver.maximize_window()
time.sleep(5)
#selecting parameters from the dropdown menu
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, "//*[#class = 'mbsc-input-wrap']")))
element.click()
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, "//*[#data-val = '66-duplicated']")))
element.click()
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, "//*[#class = 'mbsc-input-wrap']")))
element.click()
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, "//*[#data-val = '10-duplicated']")))
element.click()
What throws me off is that the code works for the 66-duplicated element but not for the 10-duplicated element, and the two are identical in every way. The error I get is
Exception has occurred: ElementClickInterceptedException
Message: element click intercepted: Element <div role="option" tabindex="-1" aria-selected="false" class="mbsc-sc-itm mbsc-sel-gr-itm mbsc-btn-e" data-index="2" data-val="10-duplicated" style="height:40px;line-height:40px;">...</div> is not clickable at point (268, 217). Other element would receive the click: <input tabindex="0" type="text" class="mbsc-sel-filter-input mbsc-control" placeholder="Hae">
To to solve this, I have tried to use javascript, move to the element and then click and maximize the window - None of which worked.
#Attempt 1:js:
driver.execute_script("arguments[0].click()", element)
#Attempt 2: moveToElement:
element = driver.find_element(by = By.XPATH, value = "//*[#data-val = '10-duplicated']")
actions = ActionChains(driver)
actions.move_to_element(element).perform()
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, "//*[#data-val = '10-duplicated']")))
element.click()
I have also tried a combination of these but to no avail.
However,when I put a break point right before the click of element "10-duplicated" and manually scroll and move the mouse to the element, and run the remaining code, it works.
I am quite puzzled here. What's going on and how can this problem be solved?
There are 17 matches for //*[#class = 'mbsc-input-wrap'] locator on that page, but you are opening the same, first match 2 times. That is Merkit droplist.
Now, when selecting //*[#data-val = '66-duplicated'] (Nissan) from the opened droplist this will work since that option is within the visible options but when Nissan is currently selected //*[#data-val = '10-duplicated'] (BMW) option in not visible, you can not click it directly.
In order to select it now you will have to
Cancel the previous selection of Nissan so that BMW will become initially visible by opening the droplist.
Scroll the droplist
Click the //*[#data-val = '10-duplicated'] with JavaScript - not recommended since this is not what human user can do via GUI.
I will give you a code to make the first approach - cancelling the previous Nissan selection.
I have also made some improvements there.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.proxy import Proxy, ProxyType
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
ser = Service(executable_path= r'D:\chromedriver.exe')
#Note I have omitted the options that I use (proxy and header).
driver = webdriver.Chrome(service = ser)
driver.get("https://www.autotalli.com/")
wait = WebDriverWait(driver, 20)
time.sleep(5)
# Accepting cookies
driver.find_element(by = By.XPATH, value = "//button[contains(text(),'Asetuks')]").click()
time.sleep(5)
driver.find_element(by = By.XPATH, value = "//button[contains(text(),'Tallenna')]").click()
driver.maximize_window()
time.sleep(5)
#selecting parameters from the dropdown menu
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#class = 'mbsc-input-wrap']"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#data-val = '66-duplicated']"))).click()
#clear the previously selected NIssan option
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(#class,'usedCarsMakeClear clearOption')]"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#class = 'mbsc-input-wrap']"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#data-val = '10-duplicated']"))).click()

Selenium isnt finding elements correctly

i want to log in to the Instagram page. I want to press the "Jetzt nicht" button, but my Selenium cant find it, no matter if im searching for the class name, or the tag name...
Could somebody please help me?
Btw: the code will be edited later :)
[see the class name etc]
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
#define webdriver
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://www.instagram.com/")
#wait 10s or till cookies loaded and accept
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "button")))
element.click()
#type username account, wait max 10s until searchbar loaded
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.NAME, "username")))
element.send_keys("yeet")
#hit enter
element.send_keys(Keys.RETURN)
#type password
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.NAME, "password")))
element.send_keys("yeet")
#hit enter
element.send_keys(Keys.RETURN)
#press the login button, press enter
element.send_keys(Keys.RETURN)
#click false on safe ur login information
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "B.sqdOP yWX7d y3zKF ")))
element.click()
sleep(30)
#quit
driver.quit()
driver.close()
(By.CLASS_NAME, "B.sqdOP yWX7d y3zKF ") locator is wrong!
By.CLASS_NAME locator receives single class name only, not multiple class names.
Also the long spaces between class names here absolutely not correct.
Also the class names you are using here seems to be dynamically changing, not something fixed.
And the B at the beginning looks to be absolutely irrelevant...
If you are using English version of instagram.com and wants to click on Not Now button which just appear once you login successfully. you can use the below code :
try:
# click false on save your login information
element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Not Now']")))
element.click()
except:
print('something went wrong')
pass
should work for you.

Can you help me type postcode into the postcode form box on this URL

I am trying to do a tutorial and learn Selenium in python however i cant seem to get Selenium to enter the postcode into the psotcode field/form box.=
I am using:
Python v3.9
Chrome v87
This is the URL i am practicing on:
https://www.currys.co.uk/app/checkout
And this is my current code:
# 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
# Open Chromedriver
driver = webdriver.Chrome(r"C:\Users\Ste1337\Desktop\chromedriver\chromedriver.exe")
# Open webpage
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")
# Click "Accept All Cookies" or ignore if no pop up
try:
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "onetrust-accept-btn-handler")))
element.click()
except Exception:
pass
# Wait 3 seconds
driver.implicitly_wait(3)
# Click "Add to Basket" or refresh page if out of stock
try:
element = WebDriverWait(driver, 1).until(EC.presence_of_element_located((By.XPATH, "email-desktop")))
time.sleep(5)
browser.refresh()
except:
button = driver.find_element_by_css_selector("button.Button__StyledButton-bvTPUF.hZIOeU.Button-jyKNMA.GZkwS")
driver.execute_script("arguments[0].click();", button)
# Wait 3 seconds
driver.implicitly_wait(3)
# Click "Continue to Basket"
button = driver.find_element_by_css_selector("button.Button__StyledButton-bvTPUF.hZIOeU.Button-jyKNMA.sc-fzpjYC.gJohPa")
driver.execute_script("arguments[0].click();", button)
# Wait 3 seconds
driver.implicitly_wait(3)
# Click "Go to checkout"
button = driver.find_element_by_xpath("//button[contains(#data-component, 'Button')][contains(#type, 'button')]")
driver.execute_script("arguments[0].click();", button)
# Type in postcode
search=WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//input[#contains='Postcode Checker")))
search.send_keys("NG229NU")
search.send_keys(Keys.RETURN)
your locator is wrong for search , use:
search = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//input[#aria-label="Postcode Checker"]')))

Selenium Webdriver (Python) - Click on a div element (checkbox)

I am trying to click on a non-button element (checkbox) inside an iframe but am not able to click on it using the selenium webdriver. The URL is https://www.nissanoflithiasprings.com/schedule-service and the box that I want to click is shown in the screenshot below:
NOTE: Select the following options to reach the screen shown in the screenshot below: Click on New Customer "MAKE. MODEL. YEAR". Select Make as "NISSAN" -> Year as "2018" -> Model as "ALTIMA" -> Trim as "SL" -> Engine Type as "I4" -> Enter Mileage as "35000" -> Click on "CONTINUE" at the bottom. On the following page, the goal is to click on the checkbox Maintenance Package Standard / Schedule 1 (the checkbox needs to be clicked but I am not able to find the correct code line for Selenium to be able to click on it)
Below is the working Selenium Python script that I wrote to successfully navigate until the page that shows the checkbox that I wish to click:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
chrome_path = r"C:\Users\gh456\Downloads\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.maximize_window()
driver.get("https://www.nissanoflithiasprings.com/schedule-service")
wait = WebDriverWait(driver, 10)
# first frame - by css selector
wait.until(ec.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, '[src^="https://consumer.xtime.com"]')))
# second frame - by ID
wait.until(ec.frame_to_be_available_and_switch_to_it('xt01'))
driver.find_element_by_id("new_customer_button").click()
driver.find_element_by_id("NISSAN").click()
wait.until(ec.visibility_of_element_located((By.ID, "2018"))).click()
wait.until(ec.visibility_of_element_located((By.ID, "ALTIMA"))).click()
wait.until(ec.visibility_of_element_located((By.ID, "SL"))).click()
wait.until(ec.visibility_of_element_located((By.ID, "I4"))).click()
wait.until(ec.visibility_of_element_located((By.NAME, "mileage_input"))).send_keys("35000")
wait.until(ec.visibility_of_element_located((By.ID, "continue_button"))).click()
# Click on the checkbox
# ---??????????????????
Can someone help me with the correct code to make selenium webdriver to click that checkbox?
The element is covered by another element...
Also, I changed the expected_conditions as element_to_be_clickable().
So you can use ActionChains:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.action_chains import ActionChains
chrome_path = r"C:\Users\gh456\Downloads\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.maximize_window()
driver.get("https://www.nissanoflithiasprings.com/schedule-service")
wait = WebDriverWait(driver, 10)
# first frame - by css selector
wait.until(ec.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, '[src^="https://consumer.xtime.com"]')))
# second frame - by ID
wait.until(ec.frame_to_be_available_and_switch_to_it('xt01'))
driver.find_element_by_id("new_customer_button").click()
driver.find_element_by_id("NISSAN").click()
wait.until(ec.element_to_be_clickable((By.ID, "2018"))).click()
wait.until(ec.element_to_be_clickable((By.ID, "ALTIMA"))).click()
wait.until(ec.element_to_be_clickable((By.ID, "SL"))).click()
wait.until(ec.element_to_be_clickable((By.ID, "I4"))).click()
wait.until(ec.visibility_of_element_located((By.NAME, "mileage_input"))).send_keys("35000")
wait.until(ec.element_to_be_clickable((By.ID, "continue_button"))).click()
check_box_el = wait.until(ec.visibility_of_element_located((By.XPATH, '//div[#id="maintenance_package_section"]//label[#class="checkbox"]')))
ActionChains(driver).move_to_element(check_box_el).click().perform()
Screenshot:
You might want to use CSS_SELECTOR and not XPATH:
check_box_el = wait.until(ec.visibility_of_element_located((By.CSS_SELECTOR, '#maintenance_package_section > div label')))
ActionChains(driver).move_to_element(check_box_el).click().perform()
Try this locator (//*[#class="checkbox"])[1] and use ActionChains.
chk = wait.until(ec.element_to_be_clickable((By.XPATH, '(//*[#class="checkbox"])[1]')))
ActionChains(driver).move_to_element(chk).click().perform()
You can change [1] to [2] or [3] if you want
It seems to be your check box is not enabled. Please, have some conditions following is_selected()...And check whether it is enabled now.....
http://selenium-interview-questions.blogspot.com/2014/03/working-with-checkboxes-in-selenium.html

Categories