selenium 使用 execute_script 设置日期时出现月日颠倒,根本原因在于目标输入框期望的日期格式(如 mm/dd/yyyy)与脚本传入的格式(如 yyyy-mm-dd)不匹配,浏览器按自身解析规则误判字段含义。
selenium 使用 execute_script 设置日期时出现月日颠倒,根本原因在于目标输入框期望的日期格式(如 mm/dd/yyyy)与脚本传入的格式(如 yyyy-mm-dd)不匹配,浏览器按自身解析规则误判字段含义。
在 Web 自动化测试中,通过 execute_script 直接向 或 等元素赋值日期字符串是一种常见做法。但需特别注意:
JavaScript 的 element.value = "..." 操作本身不进行任何日期解析或格式校验——它只是将字符串原样写入 DOM 属性
。真正的格式解释权完全交由浏览器或前端框架(如 React、Vue 绑定的日期控件)处理。
例如,当执行以下代码时:
你传入的是 ISO 标准格式 yyyy-mm-dd HH:MM(即 2024年2月20日16:00)。但若页面中该输入框实际被设计为接受美国本地格式(mm/dd/yyyy HH:MM),且其 JavaScript 监听器或后端校验逻辑默认按此解析,则 "2024-02-20" 可能被错误拆解为:
2024 → 被当作“月”(非法,但部分宽松解析器会忽略)
02 → 被当作“月”,20 → 被当作“日” → 表面无误;
而更危险的情形是:当你传入 "2024-12-05",若系统强制按 mm/dd 解析,就会变成
12月5日
(正确),但若传入 "2024-05-12",则可能被识别为
5月12日
(仍正确)——看似稳定,实则隐含风险。真正暴露问题的是当两个数字均 ≤12(如 "2024-03-04" vs "2024-04-03"),此时不同地区解析逻辑差异将直接导致月日互换。
✅ 正确做法:
始终以目标输入框实际接受的格式提供字符串
。可通过以下方式确认格式:
在浏览器开发者工具中手动输入合法日期,观察其 value 属性(右键检查 → 查看 Element → 输入后刷新查看 value= 值);
查阅前端源码或文档,确认该字段绑定的日期库(如 Flatpickr、Ant Design DatePicker)及其 format 配置;
使用 get_attribute("type") 判断是否为 date / datetime-local —— 它们有严格规范:
必须用 yyyy-MM-dd(ISO);
必须用 yyyy-MM-ddTHH:mm(如 "2024-02-20T16:00");
而普通 type="text" 则完全取决于业务逻辑,常见为 MM/DD/YYYY 或 DD/MM/YYYY。
因此,针对原文中 #start-time 字段期望 mm/dd/yyyy HH:MM 的场景,应修正为:
⚠️ 进阶注意事项:
避免硬编码格式
:建议封装为可配置函数,根据环境或页面元数据动态选择格式;
触发事件
:仅设 value 不会自动触发 change 或 input 事件,必要时补充:
时区一致性
:若涉及 datetime-local,注意该类型不含时区信息,服务端需明确约定时区(通常为本地时区);
验证回读
:赋值后建议用 get_attribute("value") 二次校验,确保浏览器未自动修正或截断。
总结:日期格式错乱不是 Selenium 的 Bug,而是人机协作中「约定未对齐」的典型表现。自动化脚本必须尊重前端的真实契约,而非假设通用标准。精准定位输入框的格式契约,是解决此类问题的唯一可靠路径。
start_time = self.driver.find_element(By.XPATH, '//*[@id="start-time"]')
self.driver.execute_script('arguments[0].value = "2024-02-20 16:00"', start_time)start_time = self.driver.find_element(By.XPATH, '//*[@id="start-time"]')
# ✅ 严格匹配前端预期格式:月/日/年 时:分
self.driver.execute_script('arguments[0].value = "02/20/2024 16:00"', start_time)self.driver.execute_script('''
arguments[0].value = "02/20/2024 16:00";
arguments[0].dispatchEvent(new Event("input", { bubbles: true }));
arguments[0].dispatchEvent(new Event("change", { bubbles: true }));
''', start_time)