新版Chrome(112+)及对应ChromeDriver已废弃旧版--headless,必须使用--headless=new,否则页面渲染失败、截图全黑;启动时仅添加--headless=new,不可混用。

ChromeDriver 启动时必须加 --headless=new,旧版 --headless 截图会空白
新版 Chrome(112+)和对应 Chromedriver 已废弃旧 headless 模式,仅用 --headless 会导致页面加载但渲染失败,截图全黑或只截到顶部一小块。这不是代码写错了,是 flag 本身已失效。
实操建议:
- 启动
webdriver.Chrome()时,options.add_argument('--headless=new')是唯一可靠写法 - 别混用
--headless和--headless=new,后者会覆盖前者且不报错,但行为不可控 - 如果用的是老旧 Selenium(
- 本地调试时可临时去掉该参数,加
--window-size=1920,1080看真实渲染效果
driver.get_screenshot_as_file() 只能截当前视口,长页面得靠 driver.execute_script() 滚动拼接
直接调 get_screenshot_as_file() 得到的只是浏览器窗口那一屏,滚动条位置不影响结果——它不自动滚动,也不合成整页。想截完整网页,必须自己控制滚动、分段截图、再用 PIL 拼接。
常见错误现象:截图只有顶部导航栏,正文全黑;或只截了首屏,后面内容缺失。
立即学习“Python免费学习笔记(深入)”;
实操建议:
- 先用
driver.execute_script('return document.body.scrollHeight')获取总高度 - 用
driver.execute_script('window.scrollTo(0, y)')分段滚动,每次滚固定像素(如 800),留 100px 重叠防断层 - 每滚一次,等
driver.execute_script('return window.pageYOffset')确认到位再截图,否则易截到未渲染区域 - 避免用
time.sleep()等待,优先用WebDriverWait等元素出现或 JS 返回值稳定
截特定 HTML 元素要用 element.screenshot(),但得先确保元素在视口内且无遮挡
WebElement.screenshot() 是 Selenium 4.0+ 提供的原生方法,比用 JS 计算坐标再截屏更稳。但它有个硬前提:目标元素必须完全出现在当前视口里,且不能被 position: fixed 的弹窗、广告、悬浮按钮盖住。
使用场景:只导出报表表格、卡片组件、二维码区域,而非整页。
实操建议:
- 调用前先做
driver.execute_script('arguments[0].scrollIntoView({block: "center"})', element) - 滚动后等 200ms,再检查
element.is_displayed()和element.size是否非空 - 若元素含阴影、圆角、SVG 图形,截图可能边缘模糊——这是 Chromium 渲染限制,不是代码问题
- 别对
display: none或visibility: hidden的元素调用,会抛InvalidElementStateException
Linux 服务器上跑无头截图,缺字体和共享内存会报 DevToolsActivePort 错误
在 Docker 容器或无桌面环境的 CentOS/Ubuntu 上启动 Chrome,常卡在初始化阶段,日志里反复出现 DevToolsActivePort file doesn't exist 或直接 timeout。根本原因不是端口冲突,而是 Chrome 启动依赖的底层资源没配齐。
性能与兼容性影响:缺这些配置,Chrome 可能降级为软件渲染,截图变慢、失真,甚至无法加载 WebFont。
实操建议:
- 启动时必须加
--no-sandbox和--disable-dev-shm-usage(尤其 Docker 场景) - 安装基础字体包:
apt-get install -y fonts-liberation xfonts-75dpi xfonts-base(Debian/Ubuntu) - 若用 Alpine,换
apk add --no-cache ttf-dejavu,别用font-noto,体积大且部分字符不生效 - 不要设
--window-size过大(如 3840x2160),容易触发 GPU 内存不足,1920x1080 最稳











