如何修复Python Selenium执行截图操作时触发的页面崩溃问题
Selenium 4 无头Chrome CI环境截图崩溃解决方案
问题根因
该报错是无头Chrome在GitLab CI这类容器资源受限环境下的常见问题,调用Selenium原生截图接口时,页面渲染/截图操作占用内存超出容器配额,触发Chrome页签崩溃,进而导致Selenium会话被销毁。
替代方案
方案1:优化Chrome启动参数修复原生截图
优先尝试配置以下启动参数,修复原生截图能力:
from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument("--headless=new") # 用新版无头模式,兼容性更好 options.add_argument("--no-sandbox") # 容器环境必须配置,禁用沙箱 options.add_argument("--disable-dev-shm-usage") # 禁用共享内存,解决Docker默认shm空间不足问题 options.add_argument("--disable-gpu") # 禁用无意义的GPU加速 options.add_argument("--window-size=1920,1080") # 固定窗口尺寸,避免渲染内存波动 options.add_argument("--disable-extensions") # 禁用扩展减少内存占用 options.add_argument("--disable-plugins") # 禁用插件减少内存占用 options.add_argument("--max_old_space_size=2048") # 限制V8引擎内存上限为2G driver = webdriver.Chrome(options=options)
绝大多数场景下配置以上参数即可解决截图崩溃问题。
方案2:调用CDP接口截图
绕过Selenium封装的原生截图方法,直接调用Chrome DevTools Protocol接口执行截图:
import base64 import io from PIL import Image # 页面加载完成后执行 screenshot_res = driver.execute_cdp_cmd("Page.captureScreenshot", { "format": "png", "fullPage": True, # 开启全页截图,不需要可删除 "captureBeyondViewport": True # 捕获视口外内容 }) # 解析截图数据 img_bytes = base64.b64decode(screenshot_res["data"]) img = Image.open(io.BytesIO(img_bytes)) img.save("screenshot.png")
该方案跳过Selenium中间层的异常校验逻辑,直接和Chrome内核通信,稳定性更高。
方案3:独立Chrome进程命令行截图
完全脱离当前Selenium会话,调用独立Chrome进程执行截图,作为兜底方案:
import subprocess # 获取当前Selenium会话打开的页面地址 current_url = driver.current_url # 调用Chrome命令行生成截图 subprocess.run( [ "google-chrome", "--headless=new", "--no-sandbox", "--disable-dev-shm-usage", "--window-size=1920,1080", "--screenshot=./screenshot.png", current_url ], check=True, timeout=30 )
该方案不受当前Selenium会话状态影响,就算Selenium会话即将崩溃也能成功生成截图。
方案4:分片截图拼接
针对超长页面截图场景,拆分截图操作降低单次内存占用:
import time import base64 import io from PIL import Image def split_full_screenshot(driver, save_path): total_height = driver.execute_script("return document.body.scrollHeight") viewport_height = driver.execute_script("return window.innerHeight") img_list = [] scroll_offset = 0 while scroll_offset < total_height: # 滚动到指定位置 driver.execute_script(f"window.scrollTo(0, {scroll_offset})") time.sleep(0.3) # 等待滚动后渲染完成 # 截取当前视口 viewport_img = Image.open(io.BytesIO(driver.get_screenshot_as_png())) img_list.append(viewport_img) scroll_offset += viewport_height # 拼接完整长图 full_img = Image.new("RGB", (img_list[0].width, total_height)) y_pos = 0 for img in img_list: full_img.paste(img, (0, y_pos)) y_pos += img.height full_img.save(save_path)
额外建议
GitLab CI运行任务时,建议将容器内存配额调整到2G以上,避免资源不足导致Chrome进程被OOM杀死。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

