Home > Net >  Python Selenium button click with SVG and Span
Python Selenium button click with SVG and Span

Time:10-05

I spent a lot of time on a seemingly simple problem but I am still looking for answers.

Here is the output from print(browser.page_source) just so I am doing my path right.

This is the button that I am trying to click with Selenium with no luck at all. I have no experience with Selenium and SVGs. I am not sure SVGs even come into play here. I thought a simple xpath with .click(0 event should do it but no dice so far.

enter image description here enter image description here

<button type="button" disabled="" class=“kl-button kl-button-pri ce-blue-button kl—button-disabled">
   <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 22 22” fill="none" stroke=“bluecolor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class=“school_search green_fields-search”>
      <circle cx="12” cy="12” r=“9”></circle>
      <path d="M17 19l-4.25-4.15"></path>
   </svg>
   School Finder<span class="green_fields_p”><span class="green_fields"></span></span>
</button>

This is what I tried so far.

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

browser = webdriver.Chrome(ChromeDriverManager().install())
# browser.get('https://google.com')
browser.get(url)

# find_all = browser.find_element_by_xpath("//div[@class='school_load']//div[2]//button[2]")
# find_all = browser.find_element_by_xpath('//*[@id="LoadResults"]/div[2]/div[2]/div[1]/div[2]/button[1]')

# browser.find_element_by_xpath('//button[@class="ce-blue-button" and child::svg[@class="school_search green_fields-search"]]').click()

# find = browser.find_element_by_xpath('//button[@class="kl-button kl-button-pri ce-blue-button kl—button-disabled"]')

find = browser.find_element_by_xpath('//button[@class="ce-blue-button"]//*[name()="svg"][@class="school_search green_fields-search"]')
print(find)
find.click()

# browser.find_element_by_xpath('//button/*[name()="svg"][@class="school_search green_fields-search"]').click()

I got output as

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element:

or

<selenium.webdriver.remote.webelement.WebElement (session="2f2ab3421ll4fd509ecbeb762bd11d8e", element="44d4ce11-5a26-412a-8md1-83c59plm7c12")>

No matter what I tried, I am unable to get the button clicked. Any help is appreciated.

CodePudding user response:

Your issue consists out of 2 separate problems.

  1. The first issue is a NoSuchElementException. This error can occur when the page is not yet loaded but the find_element code is already executed and thus couldn't find the element. I recommend using WebDriverWait to wait for the element is loaded before looking for it.
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 TimeoutException

xpath = '//button[...]'
try:
    WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH)))

    driver.find_element(By.XPATH, xpath)
    
except TimeoutException:
    print('Waiting for the element to appear on the webpage has expired. Wrong xpath?')
  1. The second issue you seem to have is not being able to click on the element. When this happens, you can always use ActionChains to move your mouse to a certain element and then click on that location.
from selenium.webdriver.common.action_chains import ActionChains

element = find_element(...)
ActionChains(driver).move_to_element(element).click().perform()

CodePudding user response:

According to code you presenting in the question you are missing a wait.
You are trying to access the element before the page is loaded.
Please try this:

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Chrome(ChromeDriverManager().install())
browser.get(url)
wait = WebDriverWait(driver, 20)

find = wait.until(EC.visibility_of_element_located((By.XPATH, '//button[@class="ce-blue-button"]//*[name()="svg"][@class="school_search green_fields-search"]')))

print(find)
find.click()

CodePudding user response:

There's a special way to locate the svg web element, Please use the below xpath

//*[local-name()='svg' and @class='“school_search']/..

There are basically 4 ways to click in Selenium.

Code trial 1 :

time.sleep(5)
driver.find_element_by_xpath("//*[local-name()='svg' and @class='“school_search']/..").click()

Code trial 2 :

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[local-name()='svg' and @class='“school_search']/.."))).click()

Code trial 3 :

time.sleep(5)
button = driver.find_element_by_xpath("//*[local-name()='svg' and @class='“school_search']/..")
driver.execute_script("arguments[0].click();", button)

Code trial 4 :

time.sleep(5)
button = driver.find_element_by_xpath("//*[local-name()='svg' and @class='“school_search']/..")
ActionChains(driver).move_to_element(button).click().perform()

Imports :

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains

PS : Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.

Steps to check:

Press F12 in Chrome -> go to element section -> do a CTRL F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.

  • Related