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

