You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用Selenium选择Datetimepicker年份无法选中2021年问题求助

问题描述

操作Selenium调用页面datetimepicker控件选择2021年作为起始年份时,代码运行后实际选中结果为2022年,原有实现代码如下:

driver.get('http://www.sse.com.cn/disclosure/bond/announcement/company/')
wait = WebDriverWait(driver, 50)
datefield_st = wait.until(EC.element_to_be_clickable((By.ID, "start_date")))
datefield_st.click()
wait.until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[12]/div[3]/table/thead/tr[1]/th[2]"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='datetimepicker-years']//table/tbody/tr/td/span[text()='{}']".format("2021")))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='datetimepicker-months']//table/tbody/tr/td/span[text()='{}']".format("十二月")))).click()
day=15
问题根因
  • 代码使用写死层级的绝对XPath定位弹窗头部按钮,datetimepicker弹窗的DOM序号会随页面渲染动态变化,极易点错翻页控件导致年份区间偏移
  • 未做年份范围校验:该站点使用的bootstrap datetimepicker年份视图默认仅展示10年区间,首次进入年份视图时默认展示的区间大概率包含当前年,若2021不在当前可见区间内直接查找元素,会触发元素不存在异常,或误点到相邻年份
  • 未做视图切换等待:点击年份/月份切换按钮后,控件有视图切换动画,未等目标视图完全渲染就执行点击,会出现点击落点偏移、命中隐藏元素的问题
  • 全局匹配元素未筛选可见状态:页面可能留存多个隐藏的历史datetimepicker DOM节点,直接全局class匹配会命中隐藏元素,点击操作不生效
修复代码
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

driver.get('http://www.sse.com.cn/disclosure/bond/announcement/company/')
wait = WebDriverWait(driver, 50)

# 触发起始日期选择框
datefield_st = wait.until(EC.element_to_be_clickable((By.ID, "start_date")))
datefield_st.click()

# 定位当前可见的激活日期弹窗,规避写死DOM序号的问题
active_picker = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.datetimepicker")))

# 点击头部切换按钮进入年份视图
switch_btn = active_picker.find_element(By.CSS_SELECTOR, "th.picker-switch")
switch_btn.click()
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.datetimepicker-years")))

# 翻页直到2021出现在可选年份列表中
while True:
    year_items = active_picker.find_elements(By.CSS_SELECTOR, "div.datetimepicker-years tbody span")
    visible_years = [item.text for item in year_items if item.is_displayed()]
    if "2021" in visible_years:
        break
    # 点击上一页箭头翻找更早年份
    prev_arrow = active_picker.find_element(By.CSS_SELECTOR, "th.prev")
    prev_arrow.click()

# 选择2021年
wait.until(EC.element_to_be_clickable(
    (By.XPATH, "//div[contains(@class,'datetimepicker-years') and not(contains(@style,'display:none'))]//span[text()='2021']")
)).click()

# 等待月份视图加载完成后选择12月
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.datetimepicker-months")))
wait.until(EC.element_to_be_clickable(
    (By.XPATH, "//div[contains(@class,'datetimepicker-months') and not(contains(@style,'display:none'))]//span[text()='十二月']")
)).click()

# 后续选择日期逻辑
day = 15
wait.until(EC.element_to_be_clickable(
    (By.XPATH, f"//div[contains(@class,'datetimepicker-days') and not(contains(@style,'display:none'))]//td[text()='{day}' and not(contains(@class,'old')) and not(contains(@class,'new'))]")
)).click()
注意事项
  • 所有控件定位优先筛选可见状态,不要匹配隐藏的DOM节点,避免点击无效
  • 禁止使用固定层级的绝对XPath定位动态弹窗元素,优先通过可见性、相对位置关系定位
  • 涉及控件多视图切换的操作,必须等待目标视图完全渲染可见后再执行下一步点击,避免动画过程中点击错位

内容的提问来源于stack exchange,提问作者Joyce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.20 16:15:50