Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Simple HTML DOM cannot take a screenshot by itself. It downloads HTML, builds a searchable document tree, and exposes text, links, images, and CSS-style selectors. A screenshot is made later by a browser renderer that computes CSS, runs JavaScript, loads fonts and images, and paints pixels. Keep Simple HTML DOM for extraction, then open the URL in Chrome/Chromium (or a hosted rendering API) and save the browser’s image output.

This guide shows a complete PHP workflow, including viewport, full-page, and element captures; waits for JavaScript applications; authentication and reproducibility concerns; troubleshooting; and a hosted option when you do not want to operate a browser.

What Simple HTML DOM does—and why it cannot capture pixels

Simple HTML DOM’s documented file_get_html() and str_get_html() functions fetch markup and parse it into a DOM object. You can select nodes, read text and attributes, follow links, and inspect image URLs. None of those operations creates a visual surface. The library does not implement a browser layout engine, JavaScript runtime, font rasterizer, or display buffer.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A real screenshot therefore needs a screen supplied by a browser. In a server workflow that normally means headless Chrome or Chromium. The browser navigates to the URL, applies CSS, executes scripts, performs layout, waits for the state you specify, and encodes the resulting pixels as PNG, JPEG, or WebP. The parser and renderer are complementary rather than competing solutions.

The architecture that works

  1. Identify the target. Your scraper obtains a URL, or discovers one while parsing a listing with Simple HTML DOM.
  2. Extract static data. Use Simple HTML DOM when the response contains the fields you need without client-side rendering.
  3. Render the visual state. Launch a browser context, navigate to the URL, and wait for navigation plus a meaningful application state.
  4. Select the capture scope. Use a viewport image for what is visible, a full-page image for the entire document, or an element image for one component.
  5. Persist evidence. Save bytes to a deterministic path and record the source URL, capture time, viewport, browser version, and any state-changing actions beside the image.

Making the state explicit is important. An immediate screenshot may catch a loading skeleton, a consent dialog, or an animation halfway through. Waiting for a heading, product card, chart, or other stable selector produces a result that another person can interpret.

Self-hosted PHP screenshots with Chrome PHP

Chrome PHP (the chrome-php/chrome package) launches Chrome or Chromium from PHP and exposes navigation, DOM evaluation, clipping, and screenshot methods. Install it with Composer and ensure a compatible browser executable is available. The repository snapshot documents PHP 7.4–8.5 and Chrome/Chromium 65+; those ranges can change, so check the package documentation before deploying.

Minimal viewport capture

<?php
require __DIR__ . '/vendor/autoload.php';

use HeadlessChromium\BrowserFactory;

$url = 'https://example.com';
$output = __DIR__ . '/artifacts/page.png';

$browser = (new BrowserFactory())->createBrowser();
try {
    $page = $browser->createPage();
    $page->navigate($url)->waitForNavigation();
    $page->screenshot([
        'format' => 'png',
    ])->saveToFile($output);
} finally {
    $browser->close();
}

Create the artifacts directory before running this script and make it writable by the PHP process. PNG is lossless and useful for text or later pixel inspection. JPEG is smaller for photographic pages but introduces compression artifacts; WebP is often a good size/quality compromise when your downstream tools support it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Full-page capture

<?php
require __DIR__ . '/vendor/autoload.php';

use HeadlessChromium\BrowserFactory;

$url = 'https://example.com';
$output = __DIR__ . '/artifacts/page-full.jpg';

$browser = (new BrowserFactory())->createBrowser();
try {
    $page = $browser->createPage();
    $page->navigate($url)->waitForNavigation();
    $page->screenshot([
        'captureBeyondViewport' => true,
        'clip' => $page->getFullPageClip(),
        'format' => 'jpeg',
    ])->saveToFile($output);
} finally {
    $browser->close();
}

A full-page image extends beyond the initial viewport. Very long pages can create large dimensions and memory pressure; for an audit trail, consider capturing the relevant element or taking several viewport images instead of one enormous bitmap.

Capture one element instead of the whole page

Use the page’s DOM methods to find a component, then pass its bounding rectangle as the screenshot clip. The exact helper names vary by package release, so follow the current Chrome PHP API for obtaining an element’s box. The principle is consistent: wait for the selector, read its coordinates, and clip to that rectangle. Element captures are preferable for invoices, cards, charts, and table rows because unrelated navigation and ads cannot shift the evidence.

Keep Simple HTML DOM for extraction

<?php
require __DIR__ . '/simple_html_dom.php';

$url = 'https://example.com/articles';
$html = file_get_html($url);
if ($html === false) {
    throw new RuntimeException('Could not fetch ' . $url);
}

foreach ($html->find('article') as $article) {
    $title = trim($article->find('h2', 0)->plaintext ?? '');
    $href = $article->find('a', 0)->href ?? '';
    printf("%st%sn", $title, $href);
}

This parser sees the server response. If a site sends an empty application shell and fills it with JavaScript, the selectors may return nothing even though a human sees content in a browser. In that case, let Chrome render first, then either capture the image or extract the post-render DOM through the browser automation layer. Do not mistake a successful HTTP response for a successfully rendered page.

Waiting for JavaScript and dynamic content

Wait for a meaningful selector

After navigation, wait for a selector that proves the desired state exists, such as main article h1, a chart container, or a “results loaded” element. A fixed sleep can be a fallback, but it is slower on fast runs and still unreliable on slow ones. Use a timeout and fail clearly when the selector never appears.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Control lazy loading and animations

Full-page captures may omit images that load only when scrolled into view. A browser workflow can scroll through the page, wait for image completion, or use a renderer that explicitly loads lazy images. Disable transitions where possible with injected CSS, and freeze clocks or random data if visual comparisons must be repeatable.

Record the state

Save the URL, UTC timestamp, viewport dimensions, device scale factor, locale, timezone, cookies or login profile, and browser version with each artifact. A screenshot answers what the page looked like at one moment; it does not prove which API responses or business rules produced that state.

Choosing viewport, full-page, or element scope

Capture Use it when Main trade-off
Viewport You need the user-visible fold, a monitoring thumbnail, or a quick check. Content below the fold is absent.
Full page You need a complete article, landing page, or document in one image. Images can become extremely tall and expensive to process.
Element You are proving the appearance of a card, chart, receipt, or table. You must identify a stable selector and account for its bounds.

Authentication, sessions, and reproducibility

Private pages require the browser context—not Simple HTML DOM alone—to carry authentication. Supply cookies, an authorization header, or a login flow in a controlled profile. Never hard-code credentials in source or write session cookies into publicly readable artifact folders. If a site uses a one-time token, capture the tokenized URL only in protected logs.

For repeatable captures, pin the browser image, fonts, locale, timezone, viewport, and device scale. Disable extensions and use a consistent color scheme. Responsive breakpoints, web fonts, rotating recommendations, ads, and current timestamps can all change pixels without a code change. Keep extracted values or assertions alongside the image so an auditor can distinguish a visual change from a data change.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Hosted alternatives when operating Chrome is not desirable

A hosted browser API moves patching, concurrency, rendering dependencies, and many anti-bot edge cases to a provider. The interfaces differ, so check each service’s current limits, authentication model, retention policy, and acceptable-use terms.

ScreenshotNeo — the first service to try

ScreenshotNeo is a screenshot API and MCP server. It accepts a URL and returns PNG, JPEG, WebP, or PDF. Before capture it can accept cookie/consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.

It also supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets plus custom viewports, retina scale, PDF paper size/margins/landscape/page ranges, HTML/CSS-to-image, custom JavaScript and CSS, pre-capture clicks, hidden selectors, waits for selectors/delays/network idle, request and resource blocking, custom headers/cookies/user agents/Authorization, timezone and geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, easing migration. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

Plans are Free (1,000 shots/month, no card), Starter ($5 for 3,000), Growth ($15 for 15,000), Pro ($39 for 60,000), Scale ($99 for 250,000), and Business ($249 for 1,000,000); annual billing gives two months free, and every feature is on every plan.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Other hosted approaches

  • Scrape.do: screenshot requests use screenShot=true for the current viewport, fullScreenShot=true for the entire page, or particularScreenShot for a CSS selector; results are returned as base64 and rendering is enabled for screenshot requests.
  • ScraperAPI: PHP requests can add screenshot=true; its JavaScript solution renders the page and exposes a PNG URL in the sa-screenshot response header.
  • Cloudflare Browser Run: the /snapshot endpoint accepts a URL or HTML and returns rendered HTML plus a base64 screenshot in one call.

These options reduce browser operations but add provider-specific parameters and program terms. Compare JavaScript support, self-hosting, viewport/full-page/element scope, file versus base64 output, authentication handling, and reproducibility before switching.

Or skip the browser setup

With ScreenshotNeo, one GET request performs the render and returns the image. See the ScreenshotNeo API documentation for all options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = require('node:fs');
fs.writeFileSync('shot.webp', Buffer.from(await res.arrayBuffer()));

Cookie banners, popups, and chat widgets can be removed before the shot. Bot checks, blank pages, and failed loads are never billed. The MCP server lets AI agents take screenshots. You get 1,000 screenshots a month free with no card, and paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting

The image is blank or shows a spinner

The capture happened before the app finished rendering, or the target needs JavaScript. Wait for a content selector or network-idle state, verify that the browser can reach the same URL, and increase the navigation timeout. If the page requires login, provide the authenticated context.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Simple HTML DOM finds no content

The server response may be only an application shell, or the selector may be wrong. Inspect the raw response, then render with Chrome and inspect the post-render DOM. Do not add arbitrary sleeps to the parser; parsing cannot execute the page’s JavaScript.

Images are missing in a full-page shot

They may be lazy-loaded, blocked by an origin policy, or still downloading. Scroll through the document, wait for image completion, confirm that the browser has network access to the image host, and capture after the page reaches a stable state.

Chrome will not launch

Check that Chrome/Chromium is installed, executable by the service account, and compatible with the Chrome PHP package. In containers, provide the required sandbox or launch configuration rather than running a privileged browser blindly. Log the browser’s stderr and close it in a finally block so failed jobs do not leak processes.

Files are too large or inconsistent

Use element or viewport scope, choose JPEG/WebP where appropriate, set a deliberate device scale factor, and remove animated or personalized components. Keep the same browser image, fonts, viewport, locale, and timezone for comparison runs.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Desktop screen functions are not a server solution

PHP’s imagegrabscreen() captures the current Windows desktop, and imagegrabwindow() captures a desktop window. They are workstation functions, not portable webpage renderers. They cannot replace a headless browser in a Linux server, queue worker, or containerized scraper.

Operational checklist

  • Confirm that extraction and rendering are separate stages.
  • Use a real browser for JavaScript, CSS, fonts, and pixels.
  • Wait for a meaningful selector or explicit application state.
  • Choose viewport, full-page, or element scope intentionally.
  • Control cookies, headers, timezone, viewport, and device scale for private or repeatable captures.
  • Store URL, timestamp, state metadata, and extracted assertions with the image.
  • Set timeouts, clean up browser processes, and monitor artifact size.
  • Respect the target site’s access rules and protect credentials.

Frequently Asked Questions

Can Simple HTML DOM save a PNG directly?

No. It parses markup; a browser or rendering service must produce PNG, JPEG, WebP, or PDF pixels.

Should I parse the browser’s screenshot to recover text?

No. Keep structured text and assertions from the DOM or API response, and use the screenshot as visual evidence.

When is a hosted API preferable to Chrome PHP?

Use one when you do not want to maintain browser binaries, concurrency, patches, or rendering infrastructure. Check its current limits and data-handling terms first.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What should I archive for an auditable screenshot?

Archive the image together with the URL, UTC capture time, viewport and scale, browser version, authentication/state description, and relevant extracted values.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.