Omar Morales Rivera
Omar Morales Rivera

Reputation: 265

How to interact with interactive elements inside iframe using Selenium

How can I interact with the ddlDelegacion (dropdown menu) element in this webpage using selenium webdriver for python? I´m doing this to periodically download some (periodically updated) documents from a government webpage for my family The HTML code is this

<div id="divFrame" style="display:block">
                <iframe id="ifrPaginaSecundaria" style="width:985px;height:330px;" frameborder="0" src="Registro/Web/wfrAcceso.aspx">
                        #document == $0
                                <html xmlns="http://www.w3.org/1999/xhtml"><head id="Head1"><title>
        ACCESO
    </title><meta charset="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1; IE=9; IE=8;"><link href="../../ScriptsJQ/jquery-ui-1.11.4.custom/jquery-ui.css" rel="stylesheet"><link rel="stylesheet" type="text/css" href="../../General/Estilos/StyleSIAP.css">
        <script src="../../ScriptsJQ/jquery-ui-1.11.4.custom/external/jquery/jquery.js" type="text/javascript"></script>
        <script src="../../ScriptsJQ/JQuery/ajaxq.js" type="text/javascript"></script>
        <script src="../../ScriptsJQ/jquery-ui-1.11.4.custom/jquery-ui.min.js" type="text/javascript"></script>
        <script src="../../ScriptsJQ/jquery-ui-1.11.4.custom/jquery-BlockUI.js" type="text/javascript"></script>
        <script language="javascript" type="text/javascript" src="../../General/Scripts/jsGeneralJQ.js"></script>
        
        <script src="../../ScriptsJQ/JQuery/jsIsNumeric.js" type="text/javascript"></script>
        <script src="../JScript/jsAcceso.js" type="text/javascript"></script>
    </head>
    <body style="">
        <table style="width:960px;">
            <tbody><tr>
               <td style="height:10px"></td>
            </tr>
            <tr>
                <td align="center">
                    <table width="330px" class="Contenedor" cellpadding="2" cellspacing="2">
                        <tbody><tr><td colspan="3" style="height:10px"></td></tr>
                        <tr>
                            <td style="width:10px"></td>
                            <td align="justify"><label class="Etiqueta">Delegación:</label></td> 
                            <td style="width:220px" align="justify"><select id="ddlDelegacion" class="capturaDrop" style="Width:205px"><option value="0">SELECCIONE OPCION</option><option value="01">AGUASCALIENTES</option><option value="02">BAJA CALIFORNIA</option><option value="03">BAJA CALIFORNIA SUR</option><option value="04">CAMPECHE</option><option value="07">CHIAPAS</option><option value="08">CHIHUAHUA</option><option value="05">COAHUILA</option><option value="06">COLIMA</option><option value="10">DURANGO</option><option value="15">ESTADO DE MEXICO ORIENTE</option><option value="16">ESTADO DE MEXICO PONIENTE</option><option value="11">GUANAJUATO</option><option value="12">GUERRERO</option><option value="13">HIDALGO</option><option value="14">JALISCO</option><option value="17">MICHOACAN</option><option value="18">MORELOS</option><option value="19">NAYARIT</option><option value="20">NUEVO LEON</option><option value="21">OAXACA</option><option value="09">OFICINAS CENTRALES</option><option value="22">PUEBLA</option><option value="23">QUERETARO</option><option value="24">QUINTANA ROO</option><option value="25">SAN LUIS POTOSI</option><option value="26">SINALOA</option><option value="27">SONORA</option><option value="28">TABASCO</option><option value="29">TAMAULIPAS</option><option value="30">TLAXCALA</option><option value="31">VERACRUZ NORTE</option><option value="32">VERACRUZ SUR</option><option value="33">YUCATAN</option><option value="34">ZACATECAS</option><option value="35">35 NORTE DEL DISTRITO FEDERAL</option><option value="36">36 NORTE DEL DISTRITO FEDERAL</option><option value="37">37 SUR DEL DISTRITO FEDERAL</option><option value="38">38 SUR DEL DISTRITO FEDERAL</option></select></td> 
        </tbody></table>
    
    
    </body></html>
                </iframe>
            </div>

My approach is this:

driver.switch_to_frame("ifrPaginaSecundaria")
delegacion=driver.find_element(By.XPATH,"/html/body/table/tbody/tr[2]/td/table/tbody/tr[2]/td[3]")
delegacion.elect_by_index(36)

However it raises this exception:

AttributeError                            Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_9740/553253340.py in <module>
     15         pass
     16 #frame=driver.find_element(By.XPATH,'//*[@id="divFrame"]')
---> 17 driver.switch_to_frame("ifrPaginaSecundaria")
     18 delegacion=driver.find_element(By.XPATH,"/html/body/table/tbody/tr[2]/td/table/tbody/tr[2]/td[3]")
     19 delegacion.elect_by_index(36)

AttributeError: 'WebDriver' object has no attribute 'switch_to_frame'

If i don´t use the driver.switch_to_frame it throws this exception despite the element being both present and visible:

NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/table/tbody/tr[2]/td/table/tbody/tr[2]/td[3]"}
  (Session info: chrome=104.0.5112.81)
Stacktrace:
Backtrace:
    Ordinal0 [0x007C5FD3+2187219]
    Ordinal0 [0x0075E6D1+1763025]
    Ordinal0 [0x00673E78+802424]
    Ordinal0 [0x006A1C10+990224]
    Ordinal0 [0x006A1EAB+990891]
    Ordinal0 [0x006CEC92+1174674]
    Ordinal0 [0x006BCBD4+1100756]
    Ordinal0 [0x006CCFC2+1167298]
    Ordinal0 [0x006BC9A6+1100198]
    Ordinal0 [0x00696F80+946048]
    Ordinal0 [0x00697E76+949878]
    GetHandleVerifier [0x00A690C2+2721218]
    GetHandleVerifier [0x00A5AAF0+2662384]
    GetHandleVerifier [0x0085137A+526458]
    GetHandleVerifier [0x00850416+522518]
    Ordinal0 [0x00764EAB+1789611]
    Ordinal0 [0x007697A8+1808296]
    Ordinal0 [0x00769895+1808533]
    Ordinal0 [0x007726C1+1844929]
    BaseThreadInitThunk [0x75C76739+25]
    RtlGetFullPathName_UEx [0x77138FEF+1215]
    RtlGetFullPathName_UEx [0x77138FBD+1165]

i´m running Python 3.9.7 and Selenium 4.3.0 and i work with Jupyter Notebooks installed with Anaconda

Upvotes: 1

Views: 549

Answers (2)

undetected Selenium
undetected Selenium

Reputation: 193058

The element is within an <iframe>

dropdown_select


Solution

To select the <option> element with index=36 you have to:

  • Induce WebDriverWait for the desired frame to be available and switch to it.

  • Induce WebDriverWait for the desired element to be clickable.

  • You can use either of the following locator strategies:

    • Using XPATH:

      driver.execute("get", {'url': 'http://rh.imss.gob.mx/tarjetonjubilados/(S(4symsfxrnmn3eneitlifwyjy))/default.aspx'})
      WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@id='ifrPaginaSecundaria']")))
      Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[@id='ddlDelegacion']")))).select_by_index(36)
      
  • 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
    
  • Browser Snapshot:

36-NORTE

Upvotes: 1

Barry the Platipus
Barry the Platipus

Reputation: 10460

While I cannot test that page, and the question does not contain full web page html, it is advisable to wait for the iframe to be available before switching to it:

WebDriverWait(browser, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//*[@id='ifrPaginaSecundaria']")))

Is that iframe nested in another iframe, or some shadowroot element? If you manage to successfully switch to it, you should also wait for the elements to load in it. You need the following imports as well:

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

Selenium documentation: https://www.selenium.dev/documentation/

Upvotes: 1

Related Questions