chrome 112+ 必须使用--headless=new,旧版--headless已废弃,否则页面渲染失败、截图全黑或仅顶部可见;混用两者会静默覆盖且行为不可控,本地调试应临时移除该参数。

Chrome 112+ 必须用 --headless=new
新版 Chrome(112 及以上)和对应 ChromeDriver 已彻底废弃旧版 --headless,仅保留 --headless=new。如果仍写 --headless,浏览器会启动但渲染失败——页面加载完成,DOM 存在,但样式、字体、JS 渲染全挂,截图结果是纯黑或只有顶部一小块灰白区域。
这不是代码逻辑问题,是 flag 本身已失效。实操中常见错误:
- 混用
--headless和--headless=new:后者会静默覆盖前者,不报错但行为不可控 - 本地调试时误加
--headless=new导致看不到渲染效果,误判为脚本问题 - 用老旧 Selenium(如 --headless=new 支持不完整
正确写法只有一条:options.add_argument('--headless=new'),且不能与其他 headless 相关参数共存。
get_screenshot_as_file() 默认只截视口,不是整页
很多人以为调用 driver.get_screenshot_as_file() 就能拿到“整个网页”,结果发现只截了顶部导航栏,正文全黑或直接空白。这是因为该方法只捕获当前浏览器窗口的可视区域(viewport),和滚动条位置无关——它不会自动滚动,也不会合成滚动后的内容。
要截长页面,必须手动控制滚动并拼接:
- 先用
driver.execute_script('return document.body.scrollHeight')获取总高度 - 用
driver.execute_script('window.scrollTo(0, y)')分段滚动,建议每次滚 800px,留 100px 重叠防断层 - 每次滚动后,等
driver.execute_script('return window.pageYOffset')返回值稳定再截图,比time.sleep()更可靠 - 最终用 PIL 拼接多张图,注意裁掉重复滚动头/尾
无头模式下字体模糊、内容缺失的根源
截图发虚、文字锯齿、按钮图标不显示,往往不是分辨率设小了,而是环境缺失导致的渲染异常:
- Chrome 在 headless 下默认禁用 HiDPI 支持,4K 屏或高缩放系统上必然模糊;加
--force-device-scale-factor=1强制像素比可缓解 - 无头模式缺少字体上下文,Linux 服务器常缺中文字体(如 Noto Sans CJK),导致中文乱码或空白;需提前安装字体包
- 某些网站通过
window.navigator.webdriver === true检测 Selenium,触发反爬策略(隐藏内容、阻断 JS 加载);需注入脚本抹除该属性 - 页面含
iframe时,get_screenshot_as_file()不会自动进入 iframe 内容区,必须先driver.switch_to.frame()切换上下文
元素截图失败:遮挡、定位、视口三重门槛
想用 element.screenshot() 截某个 div,结果报错或截出空白?这不是方法不对,而是前提没满足:
- 目标元素必须完全处于当前视口内——哪怕差 1px 在底部外,就会截不到或报
ElementNotInteractableException - 不能被
position: fixed的弹窗、广告、悬浮按钮盖住;得先用 JS 隐藏这些干扰层 - 元素可能尚未渲染完成,尤其懒加载图片或动态表格;需配合
WebDriverWait等待element_to_be_clickable或visibility_of_element_located - Shadow DOM 内部元素无法直接
find_element定位,更无法screenshot();得先用shadow_root打开边界再操作
真正麻烦的从来不是“怎么截图”,而是“怎么让页面进入一个能被稳定截图的状态”——滚动时机、JS 执行顺序、DOM 加载节奏、CSS 渲染优先级,每个环节都可能断在截图前一毫秒。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











