screenshot()默认只截可视区,因其底层调用浏览器“当前视口截图”能力,不触发滚动或拼接;长网页仅得顶部一屏,需手动滚动+分段截图+PIL拼接,并处理渲染就绪、固定定位、色彩空间等隐性依赖。

为什么 screenshot() 默认只截可视区?
因为 Selenium 4 的 driver.get_screenshot_as_file() 和 driver.get_screenshot_as_png() 底层调用的是浏览器的“当前视口截图”能力,和你在 Chrome 按 Ctrl+Shift+P → “Capture full size screenshot” 是两套机制。它不滚动、不拼接,所以长网页只会截到顶部一屏。
用 execute_script() 滚动 + 截图拼接最可靠
纯 Selenium 自带 API 不支持全页截图,必须手动控制滚动位置、逐段截图、再用 PIL 合并。关键点在于:要等滚动完成、要避开固定定位元素干扰、要处理最后一段高度不足的问题。
- 先用
driver.execute_script("return document.body.scrollHeight")获取总高度 - 用
driver.execute_script("window.scrollTo(0, arguments[0])", y)精确滚动(别用scrollIntoView,它行为不一致) - 每次截图前加
time.sleep(0.3)(尤其对 JS 渲染强的页面),否则可能截到空白或未加载内容 - 用
driver.get_window_size()得到视口高,但最后一段需用min(scroll_top + viewport_height, total_height) - scroll_top算真实截图高度
注意 ChromeOptions 中的 --headless=new 兼容性
Selenium 4.8+ 推荐用新 headless 模式,但它默认禁用某些渲染能力,导致滚动后截图内容错位或空白。必须显式启用:
options = ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
# 关键:允许生成完整布局快照
options.add_argument("--force-color-profile=srgb")
漏掉 --force-color-profile=srgb 在某些 Linux 环境下会导致截图发黑或偏色。
PIL 拼接时别忽略 driver.get_screenshot_as_png() 返回的是 RGB 而非 RGBA
直接用 Image.open(BytesIO(png_data)) 得到的是 RGB 模式图像,如果网页有透明背景(比如 body { background: none }),拼接后会出现白边或颜色断层。稳妥做法是:
- 统一转成
RGBA:img = img.convert("RGBA") - 创建透明底图:
full_img = Image.new("RGBA", (width, total_height), (255, 255, 255, 0)) - 粘贴时用
full_img.paste(img, (0, y), img)(第三个参数传自身作 mask)
滚动截图本身不难,难的是每一步都有隐性依赖:滚动时机、渲染完成判断、像素对齐、色彩空间一致性——少一个,最终图就缺一块或糊一片。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











