0

I'm trying to automate the following site - https://apps.royalbank.com/apps/home-value-estimator#!/

It works fine with the following code - but when i get to the site where I have to choose the radio-button I am not able to click on this radio-button:

 link = "https://apps.royalbank.com/apps/home-value-estimator#!/"
    WAIT = 1
    RUN = True
    driver = webdriver.Chrome (service=srv, options=options)    
    waitWebDriver = WebDriverWait (driver, 10)         
    print(f"\nChecking value for address: {address} on {link}...")
    if MINIMIZE:
      driver.minimize_window()    
    driver.get (link)    
    print(f"Input address...") 
    time.sleep(WAIT)       
    driver.find_element(By.XPATH, "//input[@name='address']").send_keys(address)    
    time.sleep(WAIT)           
    driver.find_element(By.XPATH, "//input[@name='address']").send_keys(Keys.ARROW_DOWN)    
    time.sleep(WAIT)           
    driver.find_element(By.XPATH, "//input[@name='address']").send_keys(Keys.ENTER) 
    time.sleep(WAIT)       
    driver.find_element(By.XPATH, "//form[@name='addressForm']//following-sibling::button").click()
    time.sleep(WAIT)     
    print(f"Select type...")
    if inpData[1] == "Detached House":
      driver.find_element(By.XPATH, "//label[@for='detached']").click()
    elif inpData[1] == "Condo Townhouse":
      driver.find_element(By.XPATH, "//label[@for='townhouse']").click()
    elif inpData[1] == "Semi Detached":
      driver.find_element(By.XPATH, "//label[@for='semidetached']").click()
    elif inpData[1] == "Condo Apt.":
      tmpElem = driver.find_element(By.XPATH, "//label[@for='condo']")
      if tmpElem.is_displayed():
        tmpElem.click()    
      else:
        print(f"Error - Address not found... - skipped...")
        RUN = False
    else:
      print(f"Error - Wrong Property Type {inpData[1]} in B2... - stopped...")
      RUN = False
    if RUN:    
      time.sleep(WAIT)       
      print(f"Select value and date...")
      driver.find_element(By.XPATH, "(//form[@name='typeForm']//following::button)[1]").click()
      time.sleep(WAIT)       
      driver.find_element(By.XPATH, "//input[@name='price']").send_keys(str(inpData[3]))    
      time.sleep(WAIT)       
      driver.find_element(By.XPATH, "//select[@name='month']").send_keys(str(inpData[4]))  
      time.sleep(WAIT)       
      driver.find_element(By.XPATH, "//select[@name='year']").send_keys(str(inpData[5]))    
      time.sleep(WAIT)
      driver.find_element(By.XPATH, "(//form[@name='priceForm']//following::button)[1]").click()
      time.sleep(WAIT)
      # driver.find_element(By.XPATH, "//input[@id='no-renovate']").click()      
      driver.find_element(By.XPATH, "//label[@for='no-renovate']").click()      
      time.sleep(WAIT)
      driver.find_element(By.XPATH, "(//form[@name='renovatingForm']//following::button)[1]").click()
      time.sleep(WAIT)
      print(f"Wait for value...")

It crashes at this statement:

# driver.find_element(By.XPATH, "//input[@id='no-renovate']").click()      
driver.find_element(By.XPATH, "//label[@for='no-renovate']").click() 

with the error message:

File "C:\Users\Polzi\Documents\DEV\Fiverr\TRY\Collector85\checkAddrGS.py", line 231, in <module>
    driver.find_element(By.XPATH, "//label[@for='no-renovate']").click()
  File "C:\Users\Polzi\Documents\DEV\.venv\NormalScraping\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
    self._execute(Command.CLICK_ELEMENT)
  File "C:\Users\Polzi\Documents\DEV\.venv\NormalScraping\lib\site-packages\selenium\webdriver\remote\webelement.py", line 693, in _execute
    return self._parent.execute(command, params)
  File "C:\Users\Polzi\Documents\DEV\.venv\NormalScraping\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 400, in execute
    self.error_handler.check_response(response)
  File "C:\Users\Polzi\Documents\DEV\.venv\NormalScraping\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 236, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <label class="mob-mar-b-dbl font-18-important ng-binding" for="no-renovate">...</label> is not clickable at point (1148, 360). Other element would receive the click: <div id="loader" ng-show="loading" class="loader-overlay" tabindex="-1" aria-labelledby="loading-msg" role="alert" aria-live="assertive" style="">...</div>

The part of the html-sourcecode looks like this:

<form name="renovatingForm" class="ng-valid ng-dirty ng-valid-parse" style="">
                        <fieldset class="radio-wpr pad-0 mob-mar-0 align-radio-btns mar-b-20">
                            <legend class="offscreen ng-binding"> Are You Planning on Doing Any Home Renovations?</legend>
                            <input type="radio" id="yes-renovate" name="plannedRenos" ng-model="data.hasPlannedRenos" value="1" class="ng-pristine ng-untouched ng-valid ng-not-empty" style="">
                            <label class="mob-mar-b-dbl font-18-important ng-binding" for="yes-renovate">Yes, I plan on renovating my home</label>
                            <input type="radio" id="no-renovate" name="plannedRenos" ng-model="data.hasPlannedRenos" value="0" class="ng-valid ng-not-empty ng-dirty ng-valid-parse ng-touched" style="">
                            <label class="mob-mar-b-dbl font-18-important ng-binding" for="no-renovate">No, I do not plan on renovating my home right now</label>
                        </fieldset>

                        <!-- ngIf: boughtAfter2005 --><p ng-bind-html="content.note_plan_on_renovating | trusted" class="mar-b-0 ng-binding ng-scope" ng-if="boughtAfter2005" style=""><span class="roboto-medium">Note:</span> If you’ve previously renovated your home, you will be able to add in those renovations later.</p><!-- end ngIf: boughtAfter2005 -->

                        <div class="controls-box desktop-controls-box">
                            <div class="go-back">
                                <a href="javascript:void(0);" data-dig-id="mortgages-sSX5mfsS7sZM-38" class="back-btn ng-binding" ng-click="setStep(2, data);">
                                    Back<span class="offscreen ng-binding">Click for previous Step</span>
                                </a>
                            </div>
                            <div>
                                <button href="javascript:void(0);" ng-show="data.hasPlannedRenos == 0" class="btn btn-primary ng-binding" ng-click="$root.GA4CustomEventTrigger('HVE - Planned Renovations - No Button'); setStep(5, data);" style="">
                                    Continue<span class="offscreen ng-binding">Next Step</span>
                                </button>
                                <button href="javascript:void(0);" ng-show="data.hasPlannedRenos == 1" class="btn btn-primary ng-binding ng-hide" ng-click="$root.GA4CustomEventTrigger('HVE - Planned Renovations - Yes Button'); setStep(4, data);">
                                    Continue<span class="offscreen ng-binding">Next Step</span>
                                </button>
                                <button href="javascript:void(0);" ng-show="data.hasPlannedRenos < 0" class="btn btn-primary btn-disabled ng-binding ng-hide" disabled="disabled">
                                    Continue<span class="offscreen ng-binding">Next Step</span>
                                </button>
                            </div>

                        </div>
                        <div class="controls-box mobile-controls-box">

                            <div>
                                <button href="javascript:void(0);" ng-show="data.hasPlannedRenos == 0" class="btn btn-primary ng-binding" ng-click="setStep(5, data);" style="">
                                    Continue<span class="offscreen ng-binding">Next Step</span>
                                </button>
                                <button href="javascript:void(0);" ng-show="data.hasPlannedRenos == 1" class="btn btn-primary ng-binding ng-hide" ng-click="setStep(4, data);">
                                    Continue<span class="offscreen ng-binding">Next Step</span>
                                </button>
                                <button href="javascript:void(0);" ng-show="data.hasPlannedRenos < 0" class="btn btn-primary btn-disabled ng-binding ng-hide" disabled="disabled">
                                    Continue<span class="offscreen ng-binding">Next Step</span>
                                </button>
                            </div>
                            <div class="go-back">
                                <a href="javascript:void(0);" data-dig-id="mortgages-sSX5mfsS7sZM-38" class="back-btn ng-binding" ng-click="setStep(2, data);">
                                    Back<span class="offscreen ng-binding">Click for previous Step</span>
                                </a>
                            </div>
                        </div>

                        <!--
    <a role="button" href="javascript:void(0);" ng-hide="showSanityError" class="btn-continue btn-circle fl-r mar-b-qtr price-btn" ng-click="setStep(3, data);"
       ng-class="{'fr' : lang == 'fr'}"><span class="offscreen">{{content.get_results}}</span></a>
    <a role="button" href="javascript:void(0);" ng-show="showSanityError" class="btn-continue btn-circle fl-r mar-b-qtr price-btn btn-disabled" ng-click=""
       ng-class="{'fr' : lang == 'fr'}"><span class="offscreen">{{content.get_results}}</span></a>
        -->

                        <div class="sanity-error acc-fw fl-l mobile-hide ng-binding ng-hide" ng-show="showSanityError">




                            The value entered appears to be outside the typical range for this neighbourhood (<span ng-show="lang == 'fr'" class="ng-hide">de </span> <span ng-show="lang == 'fr'" class="ng-hide">à</span><span ng-hide="lang == 'fr'">-</span> ), do you still want to continue? <a href="javascript:void(0);" ng-click="sendData(false);" class="ng-binding">Yes</a>
                        </div>


                    </form>

How can i select the radio-button using Selenium?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Rapid1898
  • 895
  • 1
  • 10
  • 32

2 Answers2

1

Walking through I was not able to repro your issue...and I believe it may be because you are using time.sleep to wait for elements to appear; drawback to this is sometimes it waits too long (a pain when debugging); or sometimes not long enough (and you error and have to iterate through testing attempts).

A better approach might be to leverage expected conditions to be met before interacting with an element. Might want to try something like below...

from selenium.common import exceptions
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC



def ClickByXPATH(NameOfObject):
    try:
        item = WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.XPATH, NameOfObject)))
        item.click()
    except TimeoutException as e:
        print("Couldn't Click by name on: " + str(NameOfObject))
        pass
#....
#driver.find_element(By.XPATH, "//label[@for='no-renovate']").click()  
ClickByXPATH("//label[@for='no-renovate']")
#...
Shawn Ramirez
  • 796
  • 1
  • 5
  • 10
1

This error message...

selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <label class="mob-mar-b-dbl font-18-important ng-binding" for="no-renovate">...</label> is not clickable at point (1148, 360). Other element would receive the click: <div id="loader" ng-show="loading" class="loader-overlay" tabindex="-1" aria-labelledby="loading-msg" role="alert" aria-live="assertive" style="">...</div>

...implies that the click event on the <label> element is being intercepted by a loader-overlay.


To click() on the <label> element:

  • First you have to induce WebDriverWait for the invisibility_of_element_located() for the loader element.

  • Then induce WebDriverWait for the desired element_to_be_clickable() and you can use either of the following locator strategies:

    • CSS_SELECTOR:

      WebDriverWait(driver, 20).until(EC.invisibility_of_element_located((By.CSS_SELECTOR, "div.loader-overlay#loader[ng-show='loading'][aria-labelledby='loading-msg']")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "label[for='no-renovate']"))).click()
      
    • XPATH:

      WebDriverWait(driver, 20).until(EC.invisibility_of_element_located((By.XPATH, "//div[@class='loader-overlay' and @id='loader'][@ng-show='loading' and @aria-labelledby='loading-msg']")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[@for='no-renovate']"))).click()
      
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • And what i also not understand - when i inspect the site and search for "//div[@class='loader-overlay']" - i can´t find anything. Why is that? – Rapid1898 Feb 24 '22 at 10:20
  • Thanks this works great! Do i understand this right - with invisibility... we wait still the element disappeared? And how did you find this div-element which you are selecting with the long xpath? – Rapid1898 Feb 24 '22 at 10:21
  • @Rapid1898 _when i inspect the site and search for "//div[@class='loader-overlay']" - i can´t find anything_: Possibly the element is a javascript/AJAX element. Inspecting the DOM can give us some clue. – undetected Selenium Feb 24 '22 at 11:14
  • @Rapid1898 _long xpath_: I just wanted to ensure that you are waiting for the exact loader to disappear as there can be multiple loaders. If the loader can be identified uniquely you can shorten the xpath as: `//div[@class='loader-overlay' and @id='loader'][@ng-show='loading']`, `//div[@class='loader-overlay' and @id='loader']`, `//div[@class='loader-overlay' and @id='loader']` or even to `//div[@class='loader-overlay']` – undetected Selenium Feb 24 '22 at 11:19