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

如何用Python抓取无参数动态航空页面?SPA爬取方法咨询

解决方案:爬取动态单页应用(SPA)类航空公司页面

针对easyfly这类URL不随搜索参数变化的动态单页应用,你可以用以下两种方案解决:

1. 用Selenium模拟完整用户交互

既然你已经在用Selenium,直接模拟用户手动搜索的流程即可,无需依赖URL参数:

  • 启动浏览器(调试阶段建议关闭无头模式,方便观察操作流程)
  • 定位出发地、目的地输入框,填入对应值
  • 模拟点击日期选择器,选择目标日期
  • 触发搜索按钮,等待页面加载完成
  • 解析加载后的页面源码提取票价

示例代码:

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
from bs4 import BeautifulSoup

# 初始化Chrome浏览器
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")  # 调试时可注释该行
driver = webdriver.Chrome(options=options)

try:
    # 打开easyfly官网
    driver.get("https://www.easyfly.com.co/")
    
    # 等待并填写出发地
    origin_input = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "origin-input"))
    )
    origin_input.send_keys("BOG")
    
    # 等待并填写目的地
    dest_input = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "destination-input"))
    )
    dest_input.send_keys("MED")
    
    # 打开日期选择器并选择目标日期
    date_input = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "departure-date"))
    )
    date_input.click()
    target_date = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, "//div[contains(@class, 'date-day') and text()='15']"))
    )
    target_date.click()
    
    # 触发搜索
    search_btn = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.ID, "search-flights-btn"))
    )
    search_btn.click()
    
    # 等待票价区域加载完成
    WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.CLASS_NAME, "flight-price"))
    )
    
    # 解析页面提取票价
    soup = BeautifulSoup(driver.page_source, "html.parser")
    for price in soup.find_all(class_="flight-price"):
        print(price.get_text(strip=True))
        
finally:
    driver.quit()

2. 抓包分析后端API,直接请求数据

动态网站的搜索结果通常来自后端API,你可以跳过页面渲染,直接调用接口获取数据:

  • 打开浏览器开发者工具(F12),切换到Network标签
  • 手动完成一次搜索操作,观察XHR/fetch类型的请求,找到返回票价数据的接口
  • 复制接口URL、请求头、请求体参数
  • 用requests库直接发送请求,解析返回的JSON数据

示例代码:

import requests

# 抓包获取的API接口地址
api_url = "https://api.easyfly.com.co/flights/search"

# 抓包获取的请求头(需包含User-Agent、Cookie等必要参数)
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",
    "Content-Type": "application/json"
}

# 抓包获取的请求体参数
payload = {
    "origin": "BOG",
    "destination": "MED",
    "departureDate": "2024-10-15",
    "adults": 1
}

response = requests.post(api_url, json=payload, headers=headers)
if response.status_code == 200:
    flight_data = response.json()
    # 根据实际返回的JSON结构提取票价
    for flight in flight_data["flights"]:
        print(f"航班号:{flight['flightNumber']},票价:{flight['price']}")
else:
    print(f"请求失败,状态码:{response.status_code}")

注意事项

  • 动态网站普遍有反爬机制,建议添加请求延时、使用代理IP,避免被封禁
  • 抓包时需注意Cookie、Authorization等会话参数,部分接口需要保持登录状态
  • Selenium定位元素时,尽量用ID、唯一类名或稳定的XPath,避免页面更新导致定位失效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:29:58