Flask中使用Selenium无头模式运行偶发页面崩溃报错求解
问题原因
- 全局复用WebDriver实例冲突:你在全局初始化了唯一的ChromeDriver实例,Flask默认会以多线程模式处理请求,多个请求同时操作同一个Driver实例时,会出现会话冲突,尤其加载资源较多的页面时很容易触发标签页崩溃。
- Replit环境资源限制:Replit的免费运行环境内存、共享内存(/dev/shm)配额极低,你提到的两个异常页面包含大量高清媒体资源、动态渲染脚本,加载时消耗的资源超过环境限制,直接导致Chrome进程崩溃。
- 启动参数缺失:你当前只配置了
--headless和--no-sandbox两个参数,缺少容器环境下运行Chrome必须的资源限制类参数,进一步放大了资源不足的问题。 - 旧版浏览器兼容问题:你使用的Chrome/ChromeDriver 91版本是2021年的旧版本,旧版headless模式存在大量已知的页面渲染崩溃Bug,部分使用了新前端特性的页面加载时会直接触发内核崩溃。
- 异常处理缺失:页面加载失败时没有对应的异常捕获和Driver重置逻辑,单次崩溃会直接导致后续所有请求都无法使用全局Driver实例。
解决方案
- 调整WebDriver实例的生命周期
不要全局初始化唯一的Driver,改为每个请求独立创建、使用完成后立即销毁,避免多线程冲突,同时补充必要的启动参数:
# 删除原有全局driver初始化逻辑,新增driver构造方法 def get_driver(): options = webdriver.ChromeOptions() options.add_argument("--headless") options.add_argument('--no-sandbox') # 新增容器环境必备参数,解决资源不足问题 options.add_argument('--disable-dev-shm-usage') options.add_argument('--disable-gpu') options.add_argument('--disable-extensions') options.add_argument('--disable-background-networking') # 不需要图片的话可以开启,大幅减少资源占用 options.add_argument('--blink-settings=imagesEnabled=false') options.add_argument('--window-size=1920,1080') # 配置通用UA,避免部分网站的兼容性拦截 options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36') driver = webdriver.Chrome(executable_path = './static/chromedriver', options = options) driver.set_page_load_timeout(15) # 设置页面加载超时,避免进程卡死 return driver @app.route('/',methods = ['GET','POST']) def parseurl(): data = None if request.method == 'GET': print("GET REq processing") return render_template('index.html') else: if "url" in request.form and "name" in request.form: URL = request.form.get("url") if validators.url(URL): org_name = request.form.get("name") driver = None try: driver = get_driver() driver.get(URL) # 用显式等待代替硬等待,可根据目标页面特性调整等待条件 from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "body"))) data = driver.page_source except Exception as e: print(f"页面加载失败: {str(e)}") data = "页面加载失败,请稍后重试" finally: if driver: driver.quit() # 请求处理完成后立即销毁driver,释放资源 return render_template('index.html',result = data)
- 升级浏览器和驱动版本
把Chrome和ChromeDriver升级到最新的稳定版,旧版本的headless模式存在大量已修复的崩溃问题,升级后可以解决大部分兼容性导致的崩溃问题。 - 高并发场景改用Driver池
如果需要处理大量请求,每次创建销毁Driver开销较大,可以用threading.local给每个线程绑定独立的Driver实例,避免重复创建,同时不会出现多线程冲突。
内容的提问来源于stack exchange,提问作者Aniiya0978
相关产品推荐
相关产品推荐

