Python+Selenium抓取kbp.aero动态航班时刻表问题求助
动态渲染航班数据抓取解决方案
问题原因说明
- requests+BeautifulSoup方案失效:该站点航班数据为页面加载完成后通过异步接口拉取后渲染,静态HTML源码中不存在目标数据,无法直接解析获取。
- 原有Selenium方案失效:一是显式等待条件设置错误,
EC.text_to_be_present_in_element第二个参数为空白字符串无法触发有效等待;二是未切换到「到达航班」对应标签页,页面默认加载出发航班数据;三是元素定位规则未匹配实际页面结构。
可行方案1:直接调用数据接口(推荐)
该站点航班数据接口无复杂鉴权规则,直接请求即可拿到结构化JSON数据,无需解析前端渲染内容,运行效率更高。示例代码如下:
import requests # 到达航班数据接口,可通过浏览器开发者工具网络面板抓包获取 URL = "https://kbp.aero/api/en/flights/arrivals?per_page=100&page=1" HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept': 'application/json' } response = requests.get(URL, headers=HEADERS) flight_data = response.json() # 提取所有到达航班信息 arrival_flights = [] for flight in flight_data['data']: arrival_flights.append({ "航班号": flight['flight'], "航空公司": flight['airline'], "出发地": flight['destination'], "预计到达时间": flight['schedule_time'], "实际到达时间": flight['actual_time'], "航班状态": flight['status'] }) # 打印结果 for item in arrival_flights: print(item)
参数说明:接口中的per_page可调整单页返回数据量,page参数可翻页获取更多历史/未来航班数据,将接口路径中的arrivals替换为departures即可获取出发航班数据。
可行方案2:修正后的Selenium方案
如果需要模拟前端操作获取渲染后的页面数据,使用修正后的代码如下:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def main(): driver = webdriver.Chrome() driver.maximize_window() driver.get("https://kbp.aero/en/") wait = WebDriverWait(driver, 15) # 切换到到达航班标签页 arrivals_tab = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a[href="#arrivals"]'))) arrivals_tab.click() # 等待航班表格内容加载完成 tbody = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#arrivals .tbody'))) wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#arrivals .tbody .tr'))) # 提取所有表格行内容 tr_list = tbody.find_elements(By.CLASS_NAME, "tr") for tr in tr_list: td_list = tr.find_elements(By.CLASS_NAME, "td") row_content = [td.text.strip() for td in td_list if td.text.strip()] if row_content: print(row_content) driver.quit() if __name__ == "__main__": main()
使用注意:需提前配置ChromeDriver版本与本地Chrome浏览器版本匹配,运行过程中不要手动操作浏览器窗口,避免元素定位失败。
内容的提问来源于stack exchange,提问作者Kovalenko Evgen
相关产品推荐
相关产品推荐

