Microlink vs Playwright for Capturing Web Page Screenshots
Compare Microlink’s hosted screenshot API with Playwright’s browser automation. See runnable examples, trade-offs, troubleshooting steps, and a managed alternative.
Choose Microlink when you want a hosted API to render a URL and return an image asset URL with metadata. Choose Playwright when you want to control the browser in your own code and save the screenshot where your application or test needs it. Neither tool is a universal quality or performance winner; the practical difference is managed delivery versus code-level browser control. That distinction follows from their official documentation, not a head-to-head benchmark. [Microlink screenshot guide; Playwright screenshots]
If you want a managed screenshot API, ScreenshotNeo is another option: it removes known consent banners, newsletter popups, and chat widgets before capture, and bills only clean shots.
How Microlink and Playwright take screenshots
Microlink: submit a URL and retrieve an asset
Microlink’s documented flow accepts a target url and screenshot option. It opens the page in a headless browser, captures the current viewport by default, stores the generated image on its CDN, and returns an asset URL and metadata such as type, size, width, and height. Its guide documents full-page and CSS-selector element capture as well. The exact options and service terms should be checked in the current documentation before implementation.
curl -G 'https://api.microlink.io' \
--data-urlencode 'url=https://example.com' \
--data-urlencode 'screenshot=true'
The response is JSON. Read data.screenshot.url to obtain the image URL; do not assume the endpoint’s JSON response itself is a PNG file.
import requests
response = requests.get(
'https://api.microlink.io',
params={'url': 'https://example.com', 'screenshot': 'true'},
timeout=60,
)
response.raise_for_status()
data = response.json()['data']
image_url = data['screenshot']['url']
print(image_url)
print(data['screenshot']) # metadata can include type, size, width, height
const params = new URLSearchParams({
url: 'https://example.com',
screenshot: 'true',
});
const response = await fetch(`https://api.microlink.io?${params}`);
if (!response.ok) throw new Error(`Microlink returned ${response.status}`);
const result = await response.json();
console.log(result.data.screenshot.url);
console.log(result.data.screenshot); // metadata
Microlink’s screenshot guide currently describes 25 no-key requests per day. Treat that quota and all plan details as changeable; check the live plan page before relying on them. [Screenshot guide; Microlink pricing]
Playwright: capture a page you control
Playwright’s screenshot API captures a page in a browser context your program launches or connects to. This example uses its documented Node.js package, saves a viewport image to disk, and closes the browser reliably.
npm install playwright
npx playwright install chromium
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
try {
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto('https://example.com', { waitUntil: 'networkidle', timeout: 60000 });
await page.screenshot({ path: 'screenshot.png' });
} finally {
await browser.close();
}
networkidle is not suitable for every site: pages with polling or long-lived connections may never become idle. For those pages, wait for a meaningful selector or use a bounded delay after navigation.
from pathlib import Path
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
try:
page = browser.new_page(viewport={"width": 1440, "height": 900})
page.goto("https://example.com", wait_until="domcontentloaded", timeout=60000)
page.locator("main").wait_for(state="visible", timeout=15000)
page.screenshot(path="screenshot.png", full_page=True)
finally:
browser.close()
Install the Python package with pip install playwright and install a browser with playwright install chromium. Playwright also supports other browser engines. Consult its current installation and screenshot references for platform-specific setup and API options. [Playwright Python introduction; Screenshot API]
What the comparison means in practice
| Question | Microlink | Playwright |
|---|---|---|
| Who operates the browser? | The hosted service handles rendering. | Your application, job, or test environment runs browser automation. |
| Where does the image go? | The response includes a hosted screenshot asset URL and metadata. | You choose the local path or other destination by handling the resulting bytes. |
| How much control do you get? | Use documented API options and supported page controls. | Use browser automation code and the APIs available in the selected Playwright language. |
| What must you operate? | Your integration and handling of API responses and service terms. | Browser installation, execution environment, concurrency, storage, and retries. |
These are workflow differences inferred from the tools’ official documentation. The sources do not establish a universal quality, speed, or cost winner. [Microlink guide; Playwright guide]
Choose based on your capture requirements
- Choose Microlink when you prefer a managed endpoint and hosted image delivery, and the documented options cover your capture needs.
- Choose Playwright when the capture belongs inside an existing browser automation workflow, or you need code-level control over page preparation and browser behavior.
- Compare both against the page itself when content depends on authentication, delayed rendering, geolocation, or interaction. Confirm the needed controls in current docs rather than assuming feature parity.
- For AI-driven capture through an MCP client, consider ScreenshotNeo’s MCP server, which offers
take_screenshot,get_page_info, andcapture_pdf.
Viewport, full-page, and element captures
A viewport screenshot records the visible browser area. A full-page screenshot extends through the page’s scrollable content. An element or clipped screenshot limits output to a target region. Choose deliberately: full-page output may be large, and a selector-based capture depends on the element being present and visible.
- Microlink: the screenshot guide documents current-viewport capture, full-page capture, and element capture by CSS selector. Follow its option syntax and inspect the returned dimensions and type.
- Playwright: use
page.screenshot({ fullPage: true })for the full page. Its screenshot API also accepts a clip rectangle and image format options; consult the API reference for the exact parameters supported by your installed version.
// Playwright full page
await page.screenshot({ path: 'full-page.png', fullPage: true });
// Playwright clipped region in CSS pixels
await page.screenshot({
path: 'region.png',
clip: { x: 0, y: 0, width: 800, height: 600 },
});
For a selector capture, wait for the element first and use the locator screenshot API:
const card = page.locator('[data-testid="product-card"]');
await card.waitFor({ state: 'visible' });
await card.screenshot({ path: 'product-card.png' });
Playwright also supports options such as PNG or JPEG type and JPEG quality. Quality applies to JPEG; check the versioned API reference for accepted formats and option behavior. [Playwright Page screenshot API]
Preparing pages and making captures repeatable
Screenshot differences often come from page state, not the screenshot call. Decide how to handle fonts, images, animations, consent dialogs, lazy-loaded sections, and personalized content. Use deterministic test data and a stable viewport when comparing captures. Wait for the specific content you need instead of relying on a generic pause.
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.locator('h1').waitFor({ state: 'visible' });
await page.evaluate(() => document.fonts.ready);
await page.screenshot({ path: 'page.png', animations: 'disabled' });
Playwright documents screenshot controls and recommends using its accessibility snapshot tooling for interaction structure rather than treating a screenshot as an interaction reference. Its screenshot documentation says: “Screenshots are for looking at, not for acting on — use browser_snapshot to get refs to interact with.” [Playwright screenshots]
Performance, reliability, and cost
Performance: total time includes navigation, page readiness, rendering, screenshot encoding, and output transfer. Microlink publishes a 2.8-second screenshot P95 claim on its product page; this is a vendor claim, not an independent head-to-head test, and workload and conditions matter. Do not use it to predict your own latency. [Microlink product page]
Reliability: with either approach, pages can fail to load, block automation, or render inconsistently. For Playwright, your deployment must have compatible browser binaries and enough resources. For a hosted service, validate its current response semantics, limits, and service terms. Microlink advertises a 99.9% SLA on paid plans; verify current scope and terms before making an availability commitment based on it. [Microlink plans]
Cost: compare current Microlink quotas and paid plans with the infrastructure and engineering time needed to run Playwright. Browser CPU, memory, concurrency, storage, retries, and maintenance affect self-hosted cost. There is no stable numeric comparison in the research, so estimate from your own capture volume and verify live pricing before choosing.
ScreenshotNeo offers a different billing model for clean results: bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with the page verdict and billing status included in response headers. Its plans are Free for 1,000 shots/month without a 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. Every feature is on every plan.
Troubleshooting screenshot captures
| Symptom | Likely cause | Fix |
|---|---|---|
| Microlink response has no screenshot URL | The request returned an error or a different response shape than expected. | Check HTTP status and the complete JSON error details before reading data.screenshot.url; confirm the URL and screenshot option match the current guide. |
| Playwright says the browser executable is missing | The package is installed but its browser binary is not. | Run the Playwright browser installation command in the same environment that runs the script. |
| Navigation or readiness wait times out | The site is slow, unavailable, or never becomes network idle. | Check the URL and network access, use a realistic timeout, and wait for a specific visible selector or DOM event when the page keeps background requests open. |
| Screenshot is blank or missing content | The capture occurs before client rendering, fonts, or images finish loading. | Wait for the page’s key selector; if relevant, await document.fonts.ready and verify the required content exists before capture. |
| Full-page screenshot is unexpectedly huge | The document is very long or contains expanding content. | Capture a viewport or a target element, or constrain the capture region; review page height before storing or transmitting the result. |
| Capture differs between runs | Dynamic content, animation, time, locale, or viewport changes. | Fix test data and viewport, disable animations where suitable, and set relevant context options consistently. |
| Microlink quota or service error | Quota, plan, or service conditions may have changed. | Check the live plan information and response details; do not hard-code assumptions from an older quota description. |
Or skip the browser setup
ScreenshotNeo provides a one-call screenshot API; see the API documentation. Replace the example URL with your target and keep your access key private.
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)
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}`);
- Cookie banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
- Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are never billed.
- An MCP server lets Claude, Cursor, and other MCP clients take screenshots, inspect pages, and capture PDFs.
- 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000.
Create a free ScreenshotNeo account to start with 1,000 screenshots a month and no card.
Frequently asked questions
Does Microlink return an image or JSON?
The documented API response is JSON containing a screenshot asset URL and metadata. Fetch the asset URL when you need the image bytes.
Can Playwright save formats other than PNG?
Yes. Its screenshot API documents image type options including JPEG, with quality configuration for JPEG. Check the API reference for your installed version.
Is one option always faster?
No general winner is established by the cited documentation. Measure with your own target pages, wait conditions, output handling, and deployment setup.
Can a screenshot tell an agent which element to click?
A screenshot is a visual capture. For structured interaction references, Playwright’s documentation points to its browser snapshot capability.
