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

使用ThreadPoolExecutor与Selenium多线程爬取航班价格异常问题咨询

Selenium多线程爬取航班价格问题修复方案

你的多线程爬取方案本身是可行的,现在拿不到数据和页面加载速度无关,是代码存在几个逻辑错误导致的:

现有代码的核心问题

  • 最严重的错误:driver.get(url) 方法没有返回值,你写的driver = driver0.get(url) 实际是把None赋值给了driver变量,后续WebDriverWait传入空对象直接报错,根本不可能找到元素。
  • 靠线程名绑定driver实例的逻辑非常脆弱:线程池的线程命名规则随Python版本、执行场景可能变化,一旦匹配失败直接拿不到可用driver。
  • Selenium的WebDriver实例本身不是线程安全的,全局提前创建3个driver跨线程调用,本身就存在偶发崩溃的风险。
  • 写死的绝对路径XPath容错性极差:谷歌航班的前端DOM是动态生成的,标签层级、序号只要随版本小幅变动,哪怕页面完全加载也定位不到元素。
  • 额外加的time.sleep(20)是无效冗余:你已经配置了显式等待,固定等待只会平白增加爬取耗时。

修正后的可运行实现

正确的多线程Selenium写法是给每个工作线程绑定独立的driver实例,复用实例处理分配到的URL,避免跨线程调用driver,同时替换不稳定的元素定位逻辑:

import pandas as pd
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 concurrent.futures import ThreadPoolExecutor
import threading
from selenium.common.exceptions import TimeoutException

# 全局存储所有初始化的driver实例,方便最后统一关闭
all_drivers = []
# 线程本地存储,每个线程绑定自己的driver实例
thread_local = threading.local()

def get_driver():
    """获取当前线程专属的driver,不存在则初始化"""
    if not hasattr(thread_local, "driver"):
        options = webdriver.ChromeOptions()
        # 无头模式,不弹出窗口,大幅提升加载速度
        options.add_argument("--headless=new")
        # 禁用图片、扩展、GPU加速,减少不必要的资源加载
        options.add_argument("--blink-settings=imagesEnabled=false")
        options.add_argument("--disable-extensions")
        options.add_argument("--disable-gpu")
        options.add_argument("--no-sandbox")
        driver = webdriver.Chrome(
            executable_path='C:\Program Files (x86)\chromedriver.exe',
            options=options
        )
        thread_local.driver = driver
        all_drivers.append(driver)
    return thread_local.driver

def get_cost(url):
    driver = get_driver()
    driver.get(url)
    cost = "-"
    try:
        # 替换为更稳定的相对定位逻辑,不要用写死的绝对XPath
        # 英文界面把选择器里的"价格"替换为"price"即可
        element = WebDriverWait(driver, 15).until(
            EC.visibility_of_element_located((By.CSS_SELECTOR, 'ul[role="list"] > li:first-child span[aria-label*="价格"]'))
        )
        cost = element.get_attribute('textContent').strip()
    except TimeoutException:
        # 仅捕获超时异常,不要裸except吞掉所有错误
        pass
    print(f"URL:{url}\n价格:{cost}\n")
    return {"url": url, "cost": cost}

if __name__ == "__main__":
    urls = ['https://www.google.com/travel/flights?q=Flights%20to%20Paphos%20from%20Vienna%20on%202022-07-25%20one%20way',
            'https://www.google.com/travel/flights?q=Flights%20to%20Paphos%20from%20Vienna%20on%202022-07-26%20one%20way', 
            'https://www.google.com/travel/flights?q=Flights%20to%20Paphos%20from%20Vienna%20on%202022-07-27%20one%20way',
            'https://www.google.com/travel/flights?q=Flights%20to%20Paphos%20from%20Vienna%20on%202022-07-28%20one%20way',
            'https://www.google.com/travel/flights?q=Flights%20to%20Paphos%20from%20Vienna%20on%202022-07-29%20one%20way', 
            'https://www.google.com/travel/flights?q=Flights%20to%20Paphos%20from%20Vienna%20on%202022-07-30%20one%20way',
            'https://www.google.com/travel/flights?q=Flights%20to%20Paphos%20from%20Vienna%20on%202022-08-01%20one%20way',
            'https://www.google.com/travel/flights?q=Flights%20to%20Paphos%20from%20Vienna%20on%202022-08-02%20one%20way', 
            'https://www.google.com/travel/flights?q=Flights%20to%20Paphos%20from%20Vienna%20on%202022-08-03%20one%20way']

    result = []
    # 线程数建议设置为2-8个,不要开太多避免触发反爬、内存占满卡顿
    with ThreadPoolExecutor(max_workers=3) as exe:
        result = list(exe.map(get_cost, urls))

    # 所有任务完成后统一关闭所有线程的driver
    for driver in all_drivers:
        driver.quit()

    # 结果转DataFrame存文件
    # pd.DataFrame(result).to_csv("flight_price.csv", index=False)

进一步优化建议

  • 如果URL规模达到十万甚至百万级,Selenium方案依然效率有限,优先用谷歌航班官方的API接口获取数据,稳定性和效率远高于页面爬取,也不需要维护元素定位规则。
  • 爬取过程中如果出现大量超时、验证页面,说明已经触发反爬,需要降低并发数、搭配代理IP池使用,不要短时间内高频请求。
  • 增加2-3次的失败重试逻辑,个别因为网络波动加载失败的URL自动重试,减少数据缺失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:36:17