# Headless Browser API for Web Scraping > Source: https://scrape.do/features/headless-browser/ Render JavaScript-heavy pages, interact with elements, capture screenshots, and extract iframes or WebSocket data. Full browser automation in a single API call. **Full Headless Browser Control, Without Managing One** Use render=true to load, render, and interact with modern web pages. Click buttons, fill forms, scroll, wait for CSS selectors, capture iframes, and extract WebSocket data — all in a single API call. ![Full Headless Browser Control, Without Managing One](/images/full-headless-browser-control.png) ## Highlights ### JavaScript Rendering - Add **render=true** to any request to load the page inside a real browser. All JavaScript-driven content, lazy-loaded data, and dynamic elements are fully rendered before the response is returned. - Supports **waitUntil** (domcontentloaded, networkidle0, networkidle2, load) and **customWait** (0–35,000 ms) to control exactly when the page is considered ready. ### Wait for CSS Selectors - Use **waitSelector** (or **waitCSSSelector**) to wait up to 10 seconds for a specific element to appear before extracting data. Perfect for pages where content loads asynchronously after the initial render. - Example: `waitSelector=.product-price` waits until `.product-price` is present in the DOM. ### Capture Frames & WebSocket Data - **showFrames=true** — Capture the content of all iframes on the page. Use with render=true and returnJSON=true. Useful for embedded widgets, payment forms, and third-party content loaded in iframes. - **showWebsocketRequests=true** — Record all WebSocket messages exchanged during page load. Ideal for real-time data sources like live scores, stock tickers, and collaborative tools. ## FAQ ### How do I enable JavaScript rendering with Scrape.do? Just add render=true to your API call. This runs the request inside a real browser environment, loading all JavaScript-driven content automatically. ### What kinds of interactions can I perform on a page? You can click elements, scroll in any direction, fill inputs, wait for elements or CSS selectors, execute custom JavaScript, and more using a simple playWithBrowser call. ### How do I wait for a specific element before scraping? Use waitSelector=.your-selector (or waitCSSSelector=.your-selector — both work identically). The browser waits up to 10 seconds for the element to appear before returning the response. URL-encode the selector value. ### Can I capture iframe content? Yes. Use showFrames=true together with render=true and returnJSON=true. The response will include a frames array with the URL and content of every iframe found on the page. ### Can I capture WebSocket messages? Yes. Use showWebsocketRequests=true together with render=true and returnJSON=true to capture WebSocket traffic from the page — useful for real-time data sources like live scores or stock tickers. ### How do I take a screenshot of a specific element? Use particularScreenShot=#yourElementSelector along with render=true and returnJSON=true. The API returns a base64-encoded image of the selected element. ### Can I scrape data that loads only after interacting with the page? Absolutely. Use click and wait actions to trigger dynamic content loading; Scrape.do renders and extracts the result just like a real browser would. ### How is using Scrape.do headless mode different from using Puppeteer or Playwright manually? There's nothing to install or maintain. Scrape.do handles rendering, interaction, and scraping in one API call, saving hours of setup and ongoing upkeep.