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

Python Selenium爬取TripAdvisor航班页遇TimeoutException问题求助

解决TripAdvisor航班爬取的TimeoutException及代码问题

核心问题分析

你遇到的TimeoutException主要是全局定位下拉按钮导致元素查找失败,同时代码里存在多处语法和逻辑错误,共同引发了执行异常:

  • 弹窗弹出后未在弹窗容器内定位元素,而是全局查找,可能匹配到其他不可见元素
  • XPATH存在语法错误(比如//@li多了@符号,@text()写法错误)
  • 列表操作、循环逻辑有错误
  • 硬编码time.sleep可靠性差,不如显式等待

修复后的完整代码

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

def extra_info(wclass, noa, nos, noc):
    # 等待主按钮可点击并点击
    mbtn = WebDriverWait(driver, 20).until(
        EC.element_to_be_clickable((By.XPATH, '//span[@class="summaryContainer target"]'))
    )
    mbtn.click()

    # 等待弹窗容器加载完成
    mdiv = WebDriverWait(driver, 20).until(
        EC.visibility_of_element_located((By.XPATH, '//div[@class="prw_rup prw_flights_cos_passenger_picker cosPassengerPopover"]'))
    )
    # 定位弹窗内容区,后续所有弹窗内元素都基于这个容器查找
    mmdiv = mdiv.find_element(By.XPATH, './/div[@class="popoverContents"]')

    # 在弹窗内容区内等待下拉按钮可点击
    drop_down_btn = WebDriverWait(mmdiv, 20).until(
        EC.element_to_be_clickable((By.XPATH, './/span[@class="ui_icon caret-down open-close"]'))
    )
    drop_down_btn.click()

    # 等待舱位选项加载,直接定位目标舱位并点击
    WebDriverWait(mmdiv, 20).until(
        EC.visibility_of_element_located((By.XPATH, f'.//li[text()="{wclass}"]'))
    )
    target_class = mmdiv.find_element(By.XPATH, f'.//li[text()="{wclass}"]')
    target_class.click()

    # 处理乘客数量
    # 定位各乘客类型的计数器容器
    adult_counter = mmdiv.find_element(By.XPATH, './/div[@class="adultCounter counter"]')
    senior_counter = mmdiv.find_element(By.XPATH, './/div[@class="seniorCounter counter"]')
    child_counter = mmdiv.find_element(By.XPATH, './/div[@class="childrenCounter counter"]')

    # 获取当前乘客数量(默认至少1个成人)
    def get_current_count(container):
        return int(container.find_element(By.XPATH, './/span[@class="count"]').text)

    current_adult = get_current_count(adult_counter)
    current_senior = get_current_count(senior_counter)
    current_child = get_current_count(child_counter)

    # 检查数量上限(成人+老人最多6,儿童最多5)
    if (noa + nos) <=6 and noc <=5:
        # 定义点击增加按钮的函数
        def add_passenger(container, target_count):
            current = get_current_count(container)
            add_btn = container.find_element(By.XPATH, './/span[@class="ui_icon plus-circle enabled"]')
            for _ in range(target_count - current):
                WebDriverWait(container, 10).until(EC.element_to_be_clickable(add_btn))
                add_btn.click()

        # 调整各类型乘客数量
        add_passenger(adult_counter, noa)
        add_passenger(senior_counter, nos)
        add_passenger(child_counter, noc)
    else:
        print('乘客数量超过上限(成人+老人最多6人,儿童最多5人)')

关键修复点说明

  1. 基于弹窗上下文定位:所有弹窗内元素通过mmdiv(弹窗内容容器)查找,用.//开头的XPATH,确保只在弹窗范围内查找,避免全局定位冲突。
  2. 替换硬编码sleep为显式等待:用WebDriverWait等待元素可见/可点击,比固定时间sleep更可靠,适应页面加载速度波动。
  3. 修正XPATH语法:
    • 去掉错误的@符号,比如//@li改为//li
    • 文本匹配用text()而非@text(),正确写法是//li[text()="Economy"]
  4. 简化舱位选择逻辑:直接通过传入的wclass参数拼接XPATH定位目标舱位,无需循环列表,更高效。
  5. 修正乘客数量逻辑:
    • 获取当前已选乘客数量,计算需要点击增加按钮的次数(目标数-当前数),避免重复点击
    • 正确判断数量上限(成人+老人总数不超过6,儿童不超过5)
  6. 修复列表操作错误:原代码plane_grades.append(eco , peco , bus , fc)语法错误,现在直接定位目标舱位,无需维护列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:25:58