Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use a real browser when you need pixels that match what users see. With Playwright, wait until the list is finished rendering, select the intended li elements, and call locator.screenshot() for each one. This produces one PNG, JPEG, or WebP file per list item. For client-side-only work, html2canvas can render each element from DOM data, but its output is a reconstruction rather than a true browser screenshot.
Choose what “every” means before writing code
The selector li matches every list-item element in the document, including items inside nested lists. That may be correct for an export, but it can also create extra images when a parent item contains a sub-list.
- All list items: use
li. - One component: scope the selector, such as
nav ul lior#plans > li. - Direct children only: use a child combinator, for example
#plans > li, after checking the page structure. - Semantic list items: Playwright’s role locator can target elements exposed as
listitem. Use a CSS selector when literallitags are required.
An li normally belongs inside ol, ul, or menu. Decide whether hidden, virtualized, or collapsed items should be included; a screenshot only represents elements that exist and are rendered in the browser at capture time.
Best automated method: Playwright screenshots
Playwright captures the browser’s final rendering, including layout, fonts, images, and CSS that the browser supports. A locator screenshot scrolls an element into view and waits for actionability checks. It can save directly to a path or return an image buffer.
#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
Install and launch a browser
npm install playwright
npx playwright install chromium
The following complete script opens a page, waits for network activity to settle, counts the matching items once, and writes one WebP file per item.
import { chromium } from 'playwright';
const targetUrl = 'https://example.com/list-page';
const browser = await chromium.launch();
const page = await browser.newPage({
viewport: { width: 1440, height: 1000 },
deviceScaleFactor: 1
});
try {
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
await page.waitForLoadState('networkidle');
// Prefer an application-specific condition when the list is populated by JavaScript.
await page.locator('ul#products').waitFor({ state: 'visible' });
const items = page.locator('ul#products > li');
const count = await items.count();
if (count === 0) throw new Error('No matching list items found');
for (let i = 0; i < count; i++) {
await items.nth(i).screenshot({
path: `item-${String(i + 1).padStart(3, '0')}.webp`,
type: 'webp',
animations: 'disabled'
});
}
} finally {
await browser.close();
}
Replace ul#products > li with the selector for your page. If you truly want nested entries, use li instead. Taking the count before the loop gives a stable set for that capture pass; if the application continues adding items, wait for its own “loaded” signal or a known count first.
PNG, JPEG, WebP, scale, and buffers
Use type: 'png' for lossless output, jpeg with a quality value for smaller photographic files, or webp for a compact modern format. scale: 'css' keeps one output pixel per CSS pixel; scale: 'device' follows the device scale and can create sharper, larger files. A buffer is useful when uploading instead of writing locally:
const image = await items.nth(0).screenshot({ type: 'png' });
await fetch('https://storage.example/upload', {
method: 'PUT',
headers: { 'content-type': 'image/png' },
body: image
});
You can set a fixed viewport, color scheme, locale, timezone, cookies, headers, or user agent when those values change the rendered list. Apply them when creating the browser context, before navigation.
Make dynamic lists deterministic
networkidle is a useful baseline, not a guarantee that an application has finished rendering. Analytics, polling, WebSockets, and advertisements can keep the network busy or change the list after it appears.
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
Wait for the application’s completion signal
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
await page.locator('[data-list-ready="true"]').waitFor({ state: 'attached' });
const items = page.locator('#results > li');
Wait for a known count
await page.waitForFunction(() => {
return document.querySelectorAll('#results > li').length >= 20;
});
Use a condition tied to your data, not an arbitrary sleep, whenever possible. Playwright’s locator.all() does not wait for matches and can behave unpredictably while a list is changing, so count or enumerate only after the page is stable.
Virtualized and lazy lists
Virtualized interfaces may create only the rows currently near the viewport. A locator count then reflects the rendered subset, not the full dataset. Capture the underlying data directly, disable virtualization for an export route, or scroll and capture batches while deduplicating item identifiers. Lazy images may need an application-ready signal and an additional image-complete check before capture.
Recommended Free Tools
What appears in an element screenshot
Playwright scrolls the target into view, but it does not remove overlays. A cookie dialog, sticky header, tooltip, or chat widget can cover part of the image and will be captured if it is on top. Dismiss or hide those elements before the loop:
await page.locator('[aria-label="Close"]').click().catch(() => {});
await page.addStyleTag({
content: '.cookie-banner, .chat-widget { display: none !important; }'
});
If the li itself is scrollable, the screenshot contains its currently visible scrolled content, not necessarily the entire scroll height. For a complete long item, redesign the capture view, expand the item, or capture its inner content after setting an appropriate scroll position.
Client-side alternative: html2canvas
html2canvas runs in the page and draws a canvas from DOM information and supported CSS. It is convenient when no browser automation service is available, but it is not a pixel screenshot. As the project documentation explains, “The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.”
Capture every matching item
const nodes = document.querySelectorAll('#products > li');
for (let i = 0; i < nodes.length; i++) {
const canvas = await html2canvas(nodes[i], {
backgroundColor: '#ffffff',
useCORS: true,
scale: window.devicePixelRatio
});
const blob = await new Promise(resolve =>
canvas.toBlob(resolve, 'image/png')
);
if (!blob) throw new Error(`Could not encode item ${i + 1}`);
const link = document.createElement('a');
link.download = `item-${i + 1}.png`;
link.href = URL.createObjectURL(blob);
link.click();
URL.revokeObjectURL(link.href);
}
Check that each node exists before passing it to html2canvas. Cross-origin images can taint the canvas unless they are served with suitable CORS headers or through a proxy. Cross-origin iframe content is not available to the page script. Unsupported CSS, filters, fonts, video, and browser-specific effects can differ from the visible page.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
Browser-native Element Capture: when permissions are acceptable
The Screen Capture API’s Element Capture approach can restrict a captured display track to an element, grab a frame with ImageCapture, and encode it through a canvas. It is a permission-based display-capture workflow, not a silent page screenshot. Your target browsers must support the required Element Capture and ImageCapture APIs, and the user must grant capture permission.
- Request display capture from the user.
- Restrict the video track to the target element using the supported Element Capture API.
- Grab a frame with
ImageCapture. - Draw the frame to a canvas and export PNG or another format.
For unattended jobs, Playwright is usually simpler because it controls navigation and does not depend on an interactive permission prompt.
Or skip the browser setup
ScreenshotNeo provides an HTTP screenshot API and an MCP server for AI agents. It can capture one element by CSS selector, load lazy images, wait for a selector, delay, or network idle, set viewport and device presets, use dark mode and retina scale, run custom CSS or JavaScript, click an element, hide selectors, block requests or resource types, supply headers, cookies, user agents, authorization, timezone, and geolocation, resize images, use transparent backgrounds, cache with a chosen TTL, create signed image links, run asynchronous jobs with signed webhooks, capture up to 100 URLs per bulk call, and return PDFs. These options let you reproduce most browser setup without maintaining Playwright infrastructure.
For a list-item capture, set the element selector to the intended CSS selector (for example, #products > li) and use the full-page or element option as appropriate. The API also accepts parameter names used by other screenshot APIs, which can simplify migration.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for the element-selector parameter and other options.
Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
Python
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)
Node.js
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(`${res.status} ${res.statusText}`);
await Bun.write('shot.webp', res);
ScreenshotNeo accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
Plans include 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Higher plans are Starter ($5/3,000), Growth ($15/15,000), Pro ($39/60,000), Scale ($99/250,000), and Business ($249/1,000,000); yearly billing gives two months free, and every feature is included on every plan. Create a free ScreenshotNeo account to start.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting checklist
No files are created
- Confirm the selector matches the intended page and that navigation reached the expected URL.
- Log
await items.count()after the readiness condition. - Check for authentication redirects, consent screens, or a frame containing the list.
The count is too high
Nested lists are included by li. Scope to a container or use a direct-child selector.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallThe count is too low
The page may be virtualized or still fetching data. Wait for an application signal, scroll to materialize rows, or capture from the source data.
Images or fonts are missing
Wait for the page’s image-ready condition, ensure the browser can reach asset hosts, and provide authentication or custom headers when required. For html2canvas, verify CORS headers and avoid cross-origin iframe dependencies.
An overlay covers the item
Dismiss it, inject CSS to hide it, or use ScreenshotNeo’s consent and popup-removal controls. A screenshot records occlusion; it does not infer what should be behind the overlay.
Best Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
The output differs from the browser
Use Playwright for final browser pixels. html2canvas may omit unsupported CSS or cross-origin content. Fix viewport, device scale, fonts, color scheme, and timing so repeated captures use the same rendering conditions.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Performance, reliability, and cost considerations
- Runtime: launching one browser and reusing a page is faster than starting a browser for every item. Capture sequentially when order and memory matter; parallel pages can increase throughput but consume more CPU and RAM.
- Memory: large, high-scale images and long list items produce large buffers. Write files or upload incrementally instead of retaining every buffer.
- Repeatability: freeze animations, use a fixed viewport and locale, and wait for deterministic readiness conditions.
- Failures: retry navigation and individual captures with bounded backoff, but do not hide persistent selector or authentication errors.
- Billing with ScreenshotNeo: only clean shots are billed; failed loads, blank pages, bot checks, CAPTCHAs, timeouts, and cache hits are identified in the response and cost nothing.
Which method should you use?
| Method | Best for | Main limitation |
|---|---|---|
| Playwright locator screenshot | Accurate automated images of rendered elements | Requires a controlled browser; dynamic content must be ready, and overlays or scroll positions affect the result |
| html2canvas | In-page, client-side rendering | DOM reconstruction, unsupported CSS, CORS, and cross-origin iframe limits |
| Screen Capture API Element Capture | Browser-native, permission-based capture | Requires user permission and support for the needed APIs |
| ScreenshotNeo | Managed API or MCP workflow with cleanup and delivery options | Requires an API key and an HTTP request |
Frequently Asked Questions
Does Playwright capture nested li elements?
Yes. A li selector includes nested list items; scope it or use a direct-child selector when nested entries should be excluded.
Can an element screenshot include the whole height of a scrollable item?
Not automatically. A scrollable target captures its currently visible scrolled content, so expand it or capture the inner content separately.
Is html2canvas a real screenshot?
No. It reconstructs an image from DOM information and supported CSS, so it can differ from browser pixels.
How do I capture items that are not yet in the DOM?
Wait for the application to finish, disable virtualization, scroll to materialize virtual rows, or export from the underlying data source.
Quick Recap
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.

