Playwright截图需先设置viewport并等待页面加载完成,优先用wait_for_load_state("networkidle")或wait_for_selector(),长截图用full_page=True,局部截图应先scroll_into_view_if_needed并校验可见性。

Playwright 截图前必须设置 viewport 和 wait_for_timeout
Playwright 默认不等待页面加载完成就截图,直接调用 screenshot() 很可能截到白屏或未渲染内容。关键不是“要不要等”,而是等什么、等多久。
常见错误是只调用 page.goto(url) 后立刻截图,结果截出空白页或缺元素。正确做法是:显式设置视口(避免响应式布局错乱),并用 wait_for_timeout() 或更可靠的 wait_for_load_state() / wait_for_selector()。
-
page.set_viewport_size({"width": 1920, "height": 1080})—— 避免某些网站根据 viewport 动态隐藏/显示内容 - 优先用
page.wait_for_load_state("networkidle")(比"load"更稳妥,等网络请求基本静默) - 若目标区域由 JS 渲染(如 React 列表),改用
page.wait_for_selector("main .content", state="visible") - 慎用
wait_for_timeout(3000)—— 纯延时不可靠,仅作兜底或调试用
长截图要禁用 clip 并启用 full_page=True
Playwright 的 screenshot() 默认只截当前视口,所谓“长截图”本质是滚动+拼接,但 Playwright 原生支持 full_page=True 参数,无需手动滚动。
容易踩的坑是:加了 clip 参数(比如想裁掉 header)却还设 full_page=True,此时 clip 会被忽略,截图仍是整页;反之,若同时设 clip 和 full_page=False,则只截视口内 clipped 区域。
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
立即学习“Python免费学习笔记(深入)”;
- 长截图:直接
page.screenshot(path="full.png", full_page=True),无需滚动逻辑 - 局部截图:用
element = page.query_selector("#chart")+element.screenshot(path="chart.png"),比clip更精准(自动适配元素位置与尺寸) - 注意
query_selector()返回None时调用screenshot()会抛TimeoutError,务必先判空或用wait_for_selector()
截图质量受 device_scale_factor 和 type 影响明显
默认截图是 1x 清晰度,文字和图标在高分屏下易发虚;导出为 jpeg 可能丢失透明背景或引入压缩噪点。这些不是“能不能截”,而是“截得清不清”。
- 提升清晰度:启动浏览器时加
device_scale_factor=2(Chromium-only),或截图时传scale="css"(保持 CSS 像素比例) - 格式选型:
type="png"(默认)支持透明、无损,适合含图表/阴影的页面;type="jpeg"体积小但不支持 alpha,且需额外指定quality=95 - 避免模糊:不要在
set_viewport_size()后再调emulate_media(media="screen"),部分站点会据此降级渲染质量
局部截图失败常因元素未进入视口或被遮挡
即使 query_selector() 找到元素,Playwright 也不保证它在可视区域内——特别是固定定位(position: fixed)的弹窗、侧边栏,或被 overflow: hidden 父容器裁切的内容。
- 安全做法:先
element.scroll_into_view_if_needed(),再截图(该方法会自动滚动并等待动画结束) - 遮挡检测:用
element.is_visible()和element.is_enabled()双重校验,比单纯查 DOM 更可靠 - 动态遮罩(如 loading overlay):加
page.wait_for_selector(".overlay", state="hidden", timeout=5000)再截图 - 截图区域偏移:若元素有 transform 或 margin-collapse,
bounding_box()返回坐标可能不准,建议用screenshot()直接作用于元素而非计算 clip
真正难的不是调哪个函数,而是判断页面当前状态是否满足截图前提——JS 是否执行完、网络是否静默、元素是否真正可交互、CSS 渲染是否完成。这些没法靠一个参数解决,得结合 wait_for_* 系列和元素状态检查来闭环验证。

















