是,默认启用;playwright python 从 v1.30+ 起,browsertype.launch() 默认 headless=true,无需显式指定,但建议显式写 headless=true 以规避版本差异风险。

Playwright Python 无头模式截图是否默认启用?
Playwright 的 BrowserType.launch() 在 Python 中默认就是无头(headless)模式,不需要额外加 headless=True 参数——但这是从 v1.30+ 开始的行为。老版本(如 1.29 及之前)默认是 headless=False,不加参数会弹窗。
- 如果你用的是较新版本(
playwright>=1.30),直接browser = playwright.chromium.launch()就是无头 - 若想显式控制,统一写成
playwright.chromium.launch(headless=True)更稳妥,避免版本差异导致本地能跑、CI 上白屏 - 真实批量截图时,建议始终显式指定
headless=True,并配合slow_mo调试(上线前关掉)
批量截图怎么避免页面加载不全或截图空白?
截图空白、截到白板、只截到 loading 状态,90% 是因为没等关键元素就调了 page.screenshot()。
- 必须等页面“视觉就绪”:优先用
page.wait_for_load_state("networkidle"),比page.wait_for_timeout(2000)可靠得多 - 若目标区域是 JS 渲染的(比如 React/Vue 动态列表),在
networkidle后补一句page.wait_for_selector("main .content", state="visible", timeout=5000) - 截图前检查
page.title()或page.query_selector("body")是否非空,防止 URL 404 却静默截图 - 批量循环中,每个
page建议独立goto()+wait_for_load_state(),别复用 page 跳转后直接截图
如何高效批量截图又不压垮内存?
开 100 个 page 对象并发截图,很容易 OOM 或触发浏览器崩溃。正确做法是控制并发数 + 复用上下文。
- 不要为每个 URL 新建
browser.new_context();一个context = browser.new_context()复用,再用context.new_page()创建页面 - 并发控制用
asyncio.Semaphore(5)(例如最多同时 5 个页面),而不是全量asyncio.gather() - 截完立刻
page.close(),不要等 context.close() 统一收尾 - 如果 URL 数量极大(>500),考虑分批执行(每批 50 个),中间
await asyncio.sleep(0.1)让事件循环喘口气
import asyncio
from playwright.async_api import async_playwright
<p>async def screenshot_one(page, url, path):
await page.goto(url, wait_until="networkidle")
await page.wait_for_selector("body", state="attached")
await page.screenshot(path=path, full_page=True)</p><p>async def batch_screenshot(urls):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
context = await browser.new_context()
sem = asyncio.Semaphore(5)</p><pre class="brush:python;toolbar:false;"> async def bounded_screenshot(url, i):
async with sem:
page = await context.new_page()
try:
await screenshot_one(page, url, f"out/{i}.png")
finally:
await page.close()
await asyncio.gather(*[bounded_screenshot(u, i) for i, u in enumerate(urls)])
await context.close()
await browser.close()
截图尺寸和裁剪怎么按需定制?
page.screenshot() 的 full_page、clip、type 参数容易混淆,尤其在批量场景下。
-
full_page=True截整个滚动页,但某些 SPA 页面会截出大量空白底部(JS 未重算高度),此时改用clip更可控 -
clip需传字典:{"x": 0, "y": 0, "width": 1200, "height": 800},注意单位是像素,且坐标基于 viewport(不是 document) - 如果要截某个元素区域,先用
elem = page.query_selector(".main-card"),再elem.screenshot(path="card.png")—— 这比全局 clip 更精准 - 格式选
type="png"(默认)或type="jpeg",后者体积小但不支持透明;批量时统一指定,避免部分文件是 PNG 部分是 JPEG 导致后续处理异常
有些网站会检测 headless 并屏蔽渲染,这时候需要加 user_agent 和禁用自动化特征,那是另一个问题了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











