如何用Selenium Python在Booking.com日历选择跨月份往返日期?
Booking.com爬虫跨月日期选择修复方案
问题根源
原代码点击入住日期后,仅获取当前显示的日历面板内的日期元素。当退房日期属于其他月份时,对应日期元素不在当前DOM中,因此无法触发选择操作。
修复后的代码实现
修改select_dates方法,新增月份切换逻辑,同时用显式等待替代固定延迟,提升稳定性:
from datetime import datetime from selenium.common.exceptions import NoSuchElementException def select_dates(self, check_in_date, check_out_date): # 解析日期为datetime对象,方便比较月份 check_in_dt = datetime.strptime(check_in_date, "%Y-%m-%d") check_out_dt = datetime.strptime(check_out_date, "%Y-%m-%d") # 点击入住日期(显式等待元素可点击) check_in_element = WebDriverWait(self, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, f'td[data-date="{check_in_date}"]')) ) check_in_element.click() # 跨月时切换到目标月份 if check_in_dt.month != check_out_dt.month: # 循环点击下月按钮,直到目标日期出现在当前日历 while True: try: # 检查目标日期是否已加载 self.find_element(By.CSS_SELECTOR, f'td[data-date="{check_out_date}"]') break except NoSuchElementException: # 点击下月箭头(需根据Booking实际DOM调整选择器) next_month_btn = WebDriverWait(self, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[aria-label="Next month"]')) ) next_month_btn.click() # 等待新日历加载完成 WebDriverWait(self, 10).until( EC.staleness_of(self.find_element(By.CSS_SELECTOR, '.bui-calendar')) ) # 点击退房日期 check_out_element = WebDriverWait(self, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, f'td[data-date="{check_out_date}"]')) ) check_out_element.click()
关键优化点
- 日期解析与月份判断:用
datetime模块解析日期,精准判断是否需要切换月份 - 显式等待替代time.sleep:避免固定延迟导致的不稳定,仅在元素可交互时执行操作
- 循环切换月份:通过异常捕获判断目标日期是否存在,直到加载对应月份的日历
- DOM加载等待:切换月份后等待旧日历DOM失效,确保新日历完全加载
额外注意事项
- 若Booking网站DOM更新,需同步调整下月按钮的CSS选择器
- 代码支持跨年选择,无需额外修改逻辑
- 切换月份后可添加0.5秒左右的短延迟,降低反爬检测风险
内容的提问来源于stack exchange,提问作者Osama Abozaid
相关产品推荐
相关产品推荐

