Skip to main content

Playwright Configuration

When "playwright": true is set (or --playwright is passed), the scraper uses headless Chromium instead of native fetch. The playwright_config block controls how that browser behaves.

When to use Playwright

Use Playwright when the target site:

  • Renders content with JavaScript after the initial page load
  • Shows a bot-detection challenge (Cloudflare, etc.) on plain HTTP requests
  • Requires authentication or cookies that must be loaded from a saved session

For static HTML pages, native fetch is faster and uses fewer resources.

Options

{
"scrape": {
"playwright": true,
"playwright_config": {
"headless": true,
"stealth": true,
"wait_for_selector": "article.main-content",
"wait_time": 3,
"page_load_timeout": 30,
"storage_state": "session.json"
}
}
}
OptionTypeDefaultDescription
headlessbooleantrueRun Chromium without a visible window. Set to false to watch the browser during debugging.
stealthbooleantrueApply stealth patches that make headless Chromium harder to detect. Bypasses Cloudflare and similar bot-detection systems.
wait_for_selectorstringnullCSS selector to wait for before capturing the page HTML. Recommended over wait_time — more reliable on variable-speed connections.
wait_timenumber3Seconds to wait after page load when wait_for_selector is not set.
page_load_timeoutnumber30Max seconds to wait for the page or selector before timing out.
storage_statestringnullPath to a saved session file (generated by writechoice session). Loads cookies and localStorage into the browser context.

Stealth Mode

Headless browsers expose several signals that bot-detection systems use to block them: navigator properties, WebGL fingerprints, Chrome runtime objects, and more. Stealth mode patches these signals so the browser looks like a normal desktop Chrome session.

It is enabled by default ("stealth": true). Disable it only if you're scraping a site with no bot detection and want to reduce startup overhead:

"playwright_config": {
"stealth": false
}

Waiting for Content

The scraper waits until the specified CSS selector appears in the DOM, then captures the page. If the selector doesn't appear within page_load_timeout seconds, the scraper continues anyway with whatever HTML is available.

Use the same selector as your content_selector when possible:

"playwright_config": {
"wait_for_selector": "article.main-content"
}

wait_time

Used when wait_for_selector is null. The scraper waits a fixed number of seconds after domcontentloaded fires. Less reliable than waiting for a selector but works when there's no stable element to target.

"playwright_config": {
"wait_for_selector": null,
"wait_time": 5
}

Authenticated Scraping

For sites behind a login, use writechoice session to capture a real browser session, then reference the saved file with storage_state. See Authenticated Scraping for the full workflow.

Debugging

Set "headless": false to open a visible browser window. This lets you watch what the scraper sees, inspect the DOM, and diagnose why content isn't being found.

"playwright_config": {
"headless": false,
"wait_for_selector": "article.main-content"
}

The browser closes automatically when the page is captured.