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

Selenium遍历网格元素问题:餐厅预约时段定位与点击异常

餐厅预约时段自动化实现方案

问题修复与优化要点

  • 定位逻辑修正:原代码依赖PARTIAL_LINK_TEXT定位时段,Resy平台的预约时段多为按钮元素而非链接,需改用更精准的XPATH/CSS选择器匹配。
  • 优先级时段遍历:按预设优先级列表依次尝试定位,优先选择高权重时段。
  • 异常与重试处理:捕获时段被抢、不可交互等异常,加入页面刷新重试机制,应对实时预约竞争场景。

完整实现代码

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException, ElementNotInteractableException, TimeoutException
import datetime
import time

# 计算两周后的预约日期
target_date = datetime.date.today() + datetime.timedelta(days=14)
target_date_str = target_date.strftime("%Y-%m-%d")
print(f"目标预约日期:{target_date_str}")

# 构造预约页面URL
booking_url = f"https://resy.com/cities/ny/lartusi-ny?date={target_date_str}&seats=2"

# 按优先级排序的目标时段列表(需匹配页面显示的文本格式,如带AM/PM)
priority_time_slots = ['8:00 PM', '7:45 PM', '7:30 PM', '8:15 PM', '7:00 PM']

timeout = 30
max_retry_rounds = 3  # 全时段列表的重试轮次
driver = webdriver.Chrome()

try:
    driver.get(booking_url)
    
    # 处理Cookie授权弹窗(根据页面实际情况启用)
    # WebDriverWait(driver, timeout).until(EC.element_to_be_clickable((By.ID, "onetrust-accept-btn-handler"))).click()

    for round_num in range(max_retry_rounds):
        print(f"第{round_num+1}轮尝试匹配时段")
        for slot in priority_time_slots:
            try:
                # 用XPATH定位包含目标时段文本的可点击按钮(可根据页面DOM结构调整)
                time_element = WebDriverWait(driver, 5).until(
                    EC.element_to_be_clickable(
                        (By.XPATH, f'//button[contains(@class, "time-slot") and contains(text(), "{slot}")]')
                    )
                )
                print(f"找到可用时段:{slot},执行点击")
                time_element.click()
                
                # 可选:验证是否进入结账流程(根据实际页面元素调整)
                # WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.CLASS_NAME, "checkout-container")))
                print(f"成功锁定时段:{slot}")
                # 此处可添加后续结账逻辑
                break
            
            except (TimeoutException, NoSuchElementException, ElementNotInteractableException):
                print(f"时段{slot}已被占用或不可用,跳过")
                continue
        
        # 本轮无可用时段,刷新页面后重试
        print("本轮优先时段全部不可用,等待5秒后刷新重试")
        time.sleep(5)
        driver.refresh()

finally:
    # 任务结束后可选择关闭浏览器
    # driver.quit()
    pass

关键细节说明

  1. 定位器适配:Resy的时段按钮通常带有time-slot类,XPATH通过文本内容匹配元素,比链接文本定位更稳定。
  2. 优先级逻辑:按列表顺序依次尝试,第一个可点击的时段即为最优选择。
  3. 异常处理:覆盖三种常见场景:超时未找到元素、元素不存在(已被抢)、元素不可交互(结账中被占用)。
  4. 重试机制:全时段遍历失败后刷新页面,重新获取最新时段数据,提升抢位成功率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:01:40