Python Selenium无法通用自动化选择MakeMyTrip日历日期
MakeMyTrip日历选择功能失效修复方案
失效原因
- 语法错误:获取日期元素列表的代码行末尾多了一个多余的英文句号,运行会直接抛语法异常
- 时序问题:点击唤起日历后没有等待面板渲染完成就直接查找元素,此时DOM还没加载完日期节点,拿到的元素列表为空
- 定位逻辑缺陷:XPath写死了class属性完全等于
DayPicker-Day,但页面上可点击、已选、禁用状态的日期class都会带额外后缀(比如DayPicker-Day--selected、DayPicker-Day--disabled),完全匹配的写法会漏掉90%以上的日期元素 - 缺少边界处理:没有做月份翻页逻辑,如果目标日期不在当前默认展示的月份,永远匹配不到元素;也没有过滤禁用状态的过往日期,就算匹配到点击也不会生效
可直接运行的通用实现代码
import time from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 配置目标日期,*格式必须和页面aria-label输出的格式完全一致* TARGET_DATE = "Sat Aug 20 2022" # 点击出发日期唤起日历面板 departure_trigger = driver.find_element(By.XPATH, '//*[@id="root"]/div/div[2]/div/div/div[2]/div[1]/div[3]/label') departure_trigger.click() # 显式等待日历面板加载完成,最长等10秒 wait = WebDriverWait(driver, 10) calendar_container = wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "DayPicker-wrapper"))) date_selected = False # 最多遍历12个月,防止死循环 for _ in range(12): # 用contains匹配class,过滤掉禁用状态的不可选日期 date_list = calendar_container.find_elements( By.XPATH, './/div[@class="DayPicker-Body"]//div[contains(@class, "DayPicker-Day") and not(contains(@class, "--disabled"))]' ) for date_item in date_list: if date_item.get_attribute("aria-label") == TARGET_DATE: date_item.click() date_selected = True break if date_selected: break # 当前月没找到目标日期则切换到下一月 next_month_btn = calendar_container.find_element(By.CLASS_NAME, "DayPicker-NavButton--next") next_month_btn.click() time.sleep(0.3) # 选完后等待交互生效 time.sleep(2)
核心优化点
- 修复原代码的语法错误
- 增加显式等待逻辑,保证日历渲染完成后再做元素查找
- 优化元素定位规则,用class包含匹配替代完全匹配,同时自动过滤不可点击的禁用日期
- 新增自动翻月逻辑,支持选择任意12个月范围内的日期,不需要手动调整月份
- 增加循环退出阈值,避免目标日期不存在时出现死循环
内容的提问来源于stack exchange,提问作者Raaghav Bhyana
相关产品推荐
相关产品推荐

