如何用Python+Selenium点击表单内指定value的Input按钮?
问题场景
我需要用Python和Selenium点击表单中value为CASTRO SALVADOR的input类型按钮,对应表单代码如下:
<form name="seleccionaEmpresaForm" action="setearContribuyente.do"> <table width="50%" align="center"> <tbody><tr><td height="5"></td></tr> <tr><td align="center"><b>Seleccione la Empresa a representar:</b></td></tr> <tr><td height="5"></td></tr> <tr> <td align="center"> <input type="hidden" name="idContribuyente" id="idcontribuyente"> <input type="button" class="btn_empresa ui-button ui-widget ui-state-default ui-corner-all" style="width:100%" value="CASTRO SALVADOR" onclick="document.getElementById('idcontribuyente').value='0';document.seleccionaEmpresaForm.submit();" role="button"> </td> </tr> <tr><td height="5"></td></tr> </tbody></table> </form>
我的代码及尝试过的定位方式
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.action_chains import ActionChains import time # 配置Firefox的Selenium驱动 driver = webdriver.Firefox() # 访问AFIP登录页面 driver.get("https://auth.afip.gov.ar/contribuyente_/login.xhtml?action=SYSTEM&system=admin_mono") WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "F1:username"))).send_keys("xxxxxx") WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "F1:btnSiguiente"))).click() WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "F1:password"))).send_keys("xxxxx") WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "F1:btnIngresar"))).click() # 等待会话初始化完成 WebDriverWait(driver, 10).until(EC.url_contains("monotributo.afip.gob.ar")) # 跳转到开票页面 driver.get("https://monotributo.afip.gob.ar/app/Facturacion.aspx") WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "bBtn1"))) # 点击开票页面的初始按钮 WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "bBtn1"))).click() # 等待元素可见(而非仅存在) driver.implicitly_wait(2) button = driver.find_element(By.XPATH, "//input[@value='CASTRO SALVADOR']") driver.execute_script("arguments[0].click();", button) button.click()
我还尝试了以下几种定位方式:
- 通过CSS选择器匹配类和value:
boton = driver.find_element(By.CSS_SELECTOR, "input.btn_empresa[value='CASTRO SALVADOR']") boton.click()
- 通过CSS选择器匹配完整类名:
boton = driver.find_element(By.CSS_SELECTOR, "input.btn_empresa.ui-button.ui-widget.ui-state-default.ui-corner-all") boton.click()
- 通过XPATH同时匹配类和value:
button = driver.find_element(By.XPATH, "//input[@class='btn_empresa' and @value='CASTRO SALVADOR']") driver.execute_script("arguments[0].click();", button)
报错信息
执行上述代码后,终端抛出如下错误:
Traceback (most recent call last): File "/Users/salvacastro/Desktop/afip.py", line 31, in <module> button = driver.find_element(By.XPATH, "//input[@class='btn_empresa' and @value='CASTRO SALVADOR']") File "/Users/salvacastro/Library/Python/3.9/lib/python/site-packages/selenium/webdriver/remote/webdriver.py", line 748, in find_element return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"] File "/Users/salvacastro/Library/Python/3.9/lib/python/site-packages/selenium/webdriver/remote/webdriver.py", line 354, in execute self.error_handler.check_response(response) File "/Users/salvacastro/Library/Python/3.9/lib/python/site-packages/selenium/webdriver/remote/errorhandler.py", line 229, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //input[@class='btn_empresa' and @value='CASTRO SALVADOR']; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception Stacktrace: RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8 WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:193:5 NoSuchElementError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:511:5 dom.find/<<@chrome://remote/content/shared/DOM.sys.mjs:136:16
解决方案
针对NoSuchElementException问题,可从以下几个方向修复:
1. 优化等待策略
当前使用的driver.implicitly_wait(2)等待时间过短,且隐式等待与显式等待混用易出现冲突。建议统一使用显式等待,确保元素完全加载可点击:
# 替换原等待和定位代码 button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, "//input[@value='CASTRO SALVADOR']")) ) button.click()
2. 修正定位表达式
- XPATH匹配class时,因元素包含多个class,精确匹配
@class='btn_empresa'会失败,改用contains匹配部分class:
button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, "//input[contains(@class, 'btn_empresa') and @value='CASTRO SALVADOR']")) )
- 或使用CSS选择器,无需匹配所有class,只需保留核心标识:
button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.CSS_SELECTOR, "input.btn_empresa[value='CASTRO SALVADOR']")) )
3. 检查iframe场景
点击bBtn1后,目标元素可能处于iframe中,需先切换到iframe再定位:
# 按iframe的ID/索引切换,需替换为实际iframe标识 WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "目标iframe的ID"))) # 定位并点击按钮 button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, "//input[@value='CASTRO SALVADOR']")) ) button.click() # 操作完成后切回主文档 driver.switch_to.default_content()
4. 直接模拟表单提交
既然按钮的点击逻辑是设置隐藏字段后提交表单,可跳过点击按钮,直接执行JS完成操作:
# 设置隐藏字段值 driver.execute_script("document.getElementById('idcontribuyente').value='0';") # 提交表单 driver.execute_script("document.seleccionaEmpresaForm.submit();")
内容的提问来源于stack exchange,提问作者Salva Castro
相关产品推荐
相关产品推荐

