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" cellpadding="2" cellspacing="2">
<tbody><tr><td colspan="3" style="height:10px"></td></tr>
<tr>
<td style="width:10px"></td>
<td align="justify"><label >Delegación:</label></td>
<td style="width:220px" align="justify"><select id="ddlDelegacion" 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
CodePudding user response:
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/
CodePudding user response:
The html-select element is within an <iframe>
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: