使用Python 3的Selenium选择日历日期遇隐藏字段问题求助
解决Selenium操作NSDL日历隐藏字段无响应的问题
问题根源
- 直接操作隐藏的
hdnDate元素无法触发页面前端逻辑:页面未监听该隐藏字段的手动修改事件,点击隐藏元素也不会产生交互反馈。 - 使用绝对XPATH定位按钮:页面结构变化时会直接失效,定位稳定性差。
- 未等待元素加载完成就操作:容易出现元素未就绪的报错。
可行解决方案
方案1:通过JS设置字段值并触发事件
直接修改隐藏字段值后手动触发change事件,让页面识别日期变更,无需打开日历弹窗,效率更高。
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException url = "https://www.fpi.nsdl.co.in/web/Reports/Archive.aspx" date_value = '2024-06-04' driver = webdriver.Chrome() driver.get(url) wait = WebDriverWait(driver, 10) try: # 等待隐藏日期字段加载完成 date_field = wait.until(EC.presence_of_element_located((By.ID, "hdnDate"))) # 设置字段值并触发change事件 driver.execute_script(""" arguments[0].value = arguments[1]; arguments[0].dispatchEvent(new Event('change')); """, date_field, date_value) # 等待并点击"查看报告"按钮(用ID+CSS定位更稳定) view_report_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a#lnkViewReport div.btn-content"))) view_report_btn.click() # 等待页面加载后点击"导出到Excel"按钮 export_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a#lnkExport div.btn-content"))) export_btn.click() except TimeoutException: print("等待元素加载超时") finally: driver.quit()
方案2:模拟手动打开日历选择日期
贴近真实用户操作,兼容性更强,适合JS触发方式失效的场景。
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException from datetime import datetime url = "https://www.fpi.nsdl.co.in/web/Reports/Archive.aspx" target_date = datetime(2024, 6, 4) driver = webdriver.Chrome() driver.get(url) wait = WebDriverWait(driver, 10) try: # 点击打开日历的可见按钮 calendar_btn = wait.until(EC.element_to_be_clickable((By.ID, "imgDate"))) calendar_btn.click() # 等待日历弹窗加载 calendar_popup = wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "ui-datepicker"))) # 切换到目标月份和年份 current_month_year = calendar_popup.find_element(By.CLASS_NAME, "ui-datepicker-month").text + " " + calendar_popup.find_element(By.CLASS_NAME, "ui-datepicker-year").text target_month_year = target_date.strftime("%B %Y") while current_month_year != target_month_year: if target_date < datetime.strptime(current_month_year, "%B %Y"): prev_btn = calendar_popup.find_element(By.CLASS_NAME, "ui-datepicker-prev") prev_btn.click() else: next_btn = calendar_popup.find_element(By.CLASS_NAME, "ui-datepicker-next") next_btn.click() current_month_year = calendar_popup.find_element(By.CLASS_NAME, "ui-datepicker-month").text + " " + calendar_popup.find_element(By.CLASS_NAME, "ui-datepicker-year").text # 选择目标日期 date_cell = calendar_popup.find_element(By.XPATH, f"//td[@data-handler='selectDay']/a[text()='{target_date.day}']") date_cell.click() # 点击查看报告按钮 view_report_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a#lnkViewReport div.btn-content"))) view_report_btn.click() # 点击导出按钮 export_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a#lnkExport div.btn-content"))) export_btn.click() except TimeoutException: print("等待元素加载超时") finally: driver.quit()
内容的提问来源于stack exchange,提问作者aardbark
相关产品推荐
相关产品推荐

