Still been having trouble creating a function in python using selenium to click a button on a webpage.
Simply I want to be able to press a button on this page (I assume the xpath is the line in the bottom right)
The solution needs to be able to interact with different sizes and I am not skilled enough in creating the xpath and I have found resources for selenium 4 online to be limited.
I've tried:
driver.find_element(By.XPATH, '//label[@value="US7.5W / US6Y"]').click()
and
driver.find_element(By.XPATH, '//label[@value="US7.5W / US6Y"]/html/body/div[2]/div[3]/div[1]/div/section/div/div[2]/div/div/div[1]/div/div/div[2]/form/div[1]/div[4]/div/div[2]/label').click()
Could anyone please help make one that doesnt give me the "no such element: Unable to locate element" error.
I am using selenium in python 3.9 running on spyder.
CodePudding user response:
I would partially agree with Anand's answer above. It would be a good idea to look out for any modal window that is hindering the actual element or window you are working on.
But I believe we should try and avoid using index in Xpath to the very possible extent. It is not considered a best practice. Now to answer your question.
You can try using a simple XPath as below.
//label[text()='US6.5W / US5Y']
CodePudding user response:
All of the sizes mentioned for the above sneakers has an associated id tagged to it. You can use that instead of using the complicated way of the xpaths. You can also use a CSS selector. I used this small code piece to click on the button and it works perfectly
import time
from seleniumwire import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
svc = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=svc)
driver.maximize_window()
def highlight(element):
"""Highlights a Selenium webdriver element"""
driver = element._parent
def apply_style(s):
driver.execute_script("arguments[0].setAttribute('style', arguments[1])", element, s)
orignal_style = element.get_attribute('style')
apply_style("border: 4px solid red")
if (element.get_attribute("style")!=None):
time.sleep(5)
apply_style(orignal_style)
driver.get("https://www.untiedau.com/products/nike-dunk-low-triple-pink-womens-gs")
time.sleep(5)
size_elem = driver.find_element(By.CSS_SELECTOR,"label[for='product-single__swatch-product-template-1-us7-5w-us6y']")
highlight(size_elem)
size_elem.click()
time.sleep(5)
driver.quit()
The highlight
method simply applies a border of 4px in red color to the element in question , to indicate this element is being worked upon. The code is written in Selenium 4 so you may or may not be familiar with it. However the code for clicking is same for Sel 3 or 4.
CodePudding user response:
Your xpaths are too long. You should try to make it more relative (although that couldn't be the issue necessarily that you got, but it's a good practice to have the xpaths as relative as possible to make them robust). One thing could be that a modal window is occasionally displayed onto the page, disabling all the page actions, as the modal gets active. So, I used a try-except block, just in case if the modal appears, the code closes it. Then, I used class in xpath with index, and the 2nd index is the one that you are looking for, perhaps, so I clicked it. If you are looking for other size button, try checking the index of it and replace with the same. This worked for me.
driver.get('https://www.untiedau.com/products/nike-dunk-low-triple-pink-womens-gs')
time.sleep(5)
try:
driver.find_element(By.XPATH, "(//*[contains(@class, 'needsclick')]//div[@role='dialog']//button)[1]").click()
except:
print('modal not shown')
time.sleep(1)
sz = driver.find_element(By.XPATH, "(//div[@class='product-single__swatch__item'])[2]")
print(sz.text)
sz.click()
Here is the output:
modal not shown
US6.5W / US5Y
Process finished with exit code 0
P.S. You may replace time.sleep
with explicit waits
such as webdriverwait