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.

Use a pathlib.Path directory, create it with mkdir(parents=True, exist_ok=True), and build each basename from a UTC timestamp plus a UUID4. Then pass that path to your capture library. The timestamp keeps files readable and sortable; the UUID4 suffix prevents practical collisions during rapid or parallel captures.

The reliable filename pattern

A screenshot is overwritten when every capture uses the same path, such as screenshots/page.png. Make the path once per capture instead:

from datetime import datetime, timezone
from pathlib import Path
from uuid import uuid4

out_dir = Path("screenshots")
out_dir.mkdir(parents=True, exist_ok=True)

name = f"shot-{datetime.now(timezone.utc):%Y%m%dT%H%M%S.%fZ}-{uuid4().hex}.png"
path = out_dir / name
print(path)

A resulting name looks like shot-20260929T142530.123456Z-8f2c...png. UTC avoids confusion between machines in different time zones. The random UUID4 component makes collisions extremely unlikely, including when several workers capture at nearly the same time. No filename scheme can promise mathematical impossibility of collision, so treat uniqueness as a property of all writers sharing the destination.

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

Use the path with Playwright

Playwright’s Python API accepts the destination through the path argument. Install it and its browser binaries in the environment where the script runs, then use the generated path:

#1 Best Overall
Sandisk 2TB Extreme Portable SSD, Up to 1050MB/s, USB-C, USB 3.2 Gen 2, IP65 Water and Dust Resistance, Updated Firmware, External Solid State Drive, SDSSDE61-2T00-G25
  • Get NVMe solid state performance with up to 1050MB/s read and 1000MB/s write speeds in a portable, high-capacity drive(1) (Based on internal testing; performance may be lower depending on host device & other factors. 1MB=1,000,000 bytes.)
  • Up to 3-meter drop protection and IP65 water and dust resistance mean this tough drive can take a beating(3) (Previously rated for 2-meter drop protection and IP55 rating. Now qualified for the higher, stated specs.)
  • Use the handy carabiner loop to secure it to your belt loop or backpack for extra peace of mind.
  • Help keep private content private with the included password protection featuring 256‐bit AES hardware encryption.(3)
  • Easily manage files and automatically free up space with the SanDisk Memory Zone app.(5). Non-Operating Temperature -20°C to 85°C
from datetime import datetime, timezone
from pathlib import Path
from uuid import uuid4
from playwright.sync_api import sync_playwright

def screenshot_path(directory="screenshots", extension="png"):
    out_dir = Path(directory)
    out_dir.mkdir(parents=True, exist_ok=True)
    stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S.%fZ")
    return out_dir / f"shot-{stamp}-{uuid4().hex}.{extension}"

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page(viewport={"width": 1440, "height": 900})
    page.goto("https://example.com", wait_until="networkidle")
    destination = screenshot_path()
    page.screenshot(path=str(destination), full_page=True)
    print(f"Saved {destination}")
    browser.close()

For asynchronous code, the same naming function works:

from playwright.async_api import async_playwright

async with async_playwright() as p:
    browser = await p.chromium.launch()
    page = await browser.new_page()
    await page.goto("https://example.com", wait_until="networkidle")
    path = screenshot_path()
    await page.screenshot(path=str(path), full_page=True)
    await browser.close()

Set full_page=True for the complete scrollable document. Omit it for the current viewport. You can also capture an element with a locator’s screenshot method and pass the same generated path.

Use the pattern with MSS for desktop captures

MSS captures monitors or regions rather than browser DOM pages. Its shot helper accepts an output filename:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from datetime import datetime, timezone
from pathlib import Path
from uuid import uuid4
import mss

def next_path():
    directory = Path("desktop-shots")
    directory.mkdir(parents=True, exist_ok=True)
    stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S.%fZ")
    return directory / f"monitor-{stamp}-{uuid4().hex}.png"

with mss.mss() as sct:
    monitor = sct.monitors[1]
    destination = next_path()
    sct.shot(mon=1, output=str(destination))
    print(f"Saved {destination}")

For a selected region, pass a monitor-like dictionary to grab() and export the returned pixels with mss.tools.to_png(..., output=str(path)). The filename logic is independent of the capture backend.

Choosing a naming strategy

Strategy Readable and sortable Collision resistance Concurrency notes Best fit
UTC timestamp only Excellent Can collide during rapid or parallel captures Requires coordination or finer precision Single, slow-running process
UUID4 only Low; opaque names Strong practical uniqueness Works well across workers Object stores and machine-oriented pipelines
Timestamp plus UUID4 Excellent Strong practical uniqueness Safe default for parallel jobs Most screenshot archives
Counter with existence check Excellent Only safe when writers coordinate Race exists between checking and creating Human-managed, mostly single-process folders

Timestamp-only names

Formatting with microseconds is convenient, but two processes can still produce the same value or write at the same instant. Use this only when one controlled writer is enough and overwriting is acceptable or separately prevented.

Rank #2
Sandisk 1TB Portable SSD, Up to 800MB/s Read Speeds, Black (Old Model)
  • Solid state performance with up to 800MB/s read speeds in a portable drive. (Based on internal testing; performance may be lower depending on host device, interface, usage conditions and other factors. 1MB=1,000,000 bytes.)
  • Back up your content and memories on a storage solution that fits seamlessly into your mobile lifestyle.
  • Take it with you on your adventures—up to two-meter drop protection means this durable drive can take a beating. (Based on internal testing.)
  • Secure it to your belt loop or backpack for extra peace of mind thanks to the tough rubber hook.
  • From Sandisk, a brand professional photographers trust to take on assignments.

UUID4 names

Python documents uuid4() as creating a random UUID. Its hexadecimal form is compact and avoids punctuation that can be inconvenient in URLs or object keys. Add a semantic prefix such as homepage- or monitor- when operators need to identify the capture type.

Counters

A simple sequence is easy to read, but check-and-create must be coordinated:

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

def next_counter_path(directory="screenshots"):
    folder = Path(directory)
    folder.mkdir(parents=True, exist_ok=True)
    number = 1
    while True:
        candidate = folder / f"shot-{number:06d}.png"
        if not candidate.exists():
            return candidate
        number += 1

This loop is not an atomic reservation. Two processes can both observe a missing file and select it. For multi-process jobs, prefer UUID4 or create files with exclusive operating-system semantics before writing.

Keep extensions and formats consistent

Choose the extension that matches the encoder. Playwright commonly writes PNG, JPEG, or WebP according to its screenshot options; MSS’s documented export path is PNG. Do not label JPEG bytes as .png. If you resize or convert after capture, write the converted data to a second uniquely generated path or replace the original deliberately.

Prevent partial files and accidental overwrites

  • Generate the final path immediately before capture, not once at module import time.
  • Use one output directory per job, tenant, or date when retention and cleanup need separation.
  • For long-running workers, include a job identifier or URL hash in the readable prefix, while retaining UUID4 for uniqueness.
  • Write to a temporary name and rename it after a successful encode when downstream consumers must never see incomplete files. A same-directory rename is typically the safest pattern because it stays on one filesystem.
  • Do not trust a URL or page title directly as a basename; strip path separators and control characters, and limit length. Keep untrusted metadata in a separate manifest.

Operating a high-volume capture job

Parallel workers

Each worker can call the same naming function because UUID4 does not depend on a shared counter. Avoid sharing a mutable global filename. If a database or object store assigns the final key, keep the generated path as a temporary local name and record the assigned key in metadata.

Rank #3
SSK Portable SSD 500GB External Solid State Hard Drive USB C Up to 1050MB/s
  • Capacity Display Variance: 500GB external ssd often appears as around 465GB on Windows. MacOS can show full 500 GB capacity. This is binary calculation difference and doesn’t affect SSD hard drive actual physical storage
  • 1050 MB/s Speed: Instantly access to your files with blazing-fast 10Gbps external SSD read up to 1050MB/s and write up to 1000MB/s. LED Light indicates USB SSD instant activity
  • Data Security: Solid state drives S.M.A.R.T. health diagnostics​ and adaptive TRIM optimizing data block management ensures consistent write speeds and extends the longevity of the portable SSD
  • USB-C & USB-A Cable: Both cables featuring rapid USB 3.2 Gen2, this USB SSD effortlessly bridges devices, enabling seamless cross-platform file transfers and backup between computers, smartphones, tablets and iPhone
  • Always Fast: No slowdowns for large file transfers. With SLC caching (25% of current available capacity allocated as high-speed cache), this external SSD delivers steady 10Gbps for transfers within the cache capacity

Sorting and retention

The UTC prefix sorts lexicographically in capture order for normal clock behavior. It is not a substitute for a monotonic sequence when system clocks can move backward. Add file age or job metadata to your cleanup policy rather than parsing names alone.

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

Capture cost and performance

Filename generation is negligible compared with launching a browser, loading a page, rendering fonts, and encoding an image. Reuse a Playwright browser for many pages, limit concurrency to available CPU and memory, and choose viewport or full-page capture intentionally. MSS avoids browser startup for desktop regions but captures what is on screen, including transient UI.

Troubleshooting

Every image still has the same name

Check that datetime.now(...) and uuid4() are inside the capture function or loop. Printing path before the screenshot call should show a different value for every iteration.

“No such file or directory”

The parent directory was not created, or a relative path resolves somewhere unexpected. Call mkdir(parents=True, exist_ok=True) and log path.resolve() while diagnosing the working directory.

Permission denied

Choose a directory writable by the account running the worker. In containers and services, mount a writable volume and verify its user/group ownership instead of changing permissions broadly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Sandisk 1TB Extreme Portable SSD, Up to 2000MB/s Transfer Speeds-New Model
  • NEARLY 2X FASTER THAN OUR PREVIOUS GENERATION(8) – move 1,000 high-res photos in under 60 seconds(6) with up to 2000MB/s transfer speeds(2).
  • IP65 RATING AND UP TO 3M DROP PROTECTION(3) – protects against spills and drops.
  • POCKET-SIZED – fits easily in pockets and small bags.
  • SPACE TO OWN YOUR AI CONTENT – speed and capacity to download your high-res clips and photo edits.
  • 256-BIT AES ENCRYPTION(4) – helps keep private files secure with password protection.

Files collide only under load

A timestamp-only or counter scheme is racing. Switch to timestamp plus UUID4, or use an atomic exclusive-create workflow. Also verify that separate workers are not truncating a shared temporary filename.

Playwright captures a blank or incomplete page

Wait for an appropriate readiness condition, such as networkidle or a specific locator, and allow lazy content to render. A screenshot path cannot fix a page that has not finished loading.

MSS captures the wrong monitor or region

Inspect sct.monitors; index 1 is commonly the first physical monitor, while index 0 represents the combined virtual desktop in MSS. Select and test the region explicitly.

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

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF, while its capture pipeline accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result.

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

See the parameter details in the ScreenshotNeo documentation. This Python example saves the response under the same timestamp-plus-UUID pattern:

import requests
from datetime import datetime, timezone
from pathlib import Path
from uuid import uuid4

out_dir = Path("screenshots")
out_dir.mkdir(parents=True, exist_ok=True)
name = f"shot-{datetime.now(timezone.utc):%Y%m%dT%H%M%S.%fZ}-{uuid4().hex}.webp"
path = out_dir / name

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()
path.write_bytes(r.content)
print(path, r.headers.get("X-Page-Verdict"), r.headers.get("X-Billed"))

ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. It includes full-page and element capture, device and retina settings, custom CSS and JavaScript, waits, request blocking, headers, cookies, geolocation, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, caching with a chosen TTL, and an API for usage. Every feature is on every plan: 1,000 shots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Best Value
Sale
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
  • Easily store and access 2TB to content on the go with the Seagate Portable Drive, a USB external hard drive
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
  • To get set up, connect the portable hard drive to a computer for automatic recognition no software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.

FAQ

Are UUID filenames cryptographically secure?

UUID4 is designed for practical identifier uniqueness, not as a secret or access-control mechanism. Do not put credentials in filenames.

Should I include the URL in the filename?

Only after sanitizing and truncating it. A short stable label plus UUID4 is safer; retain the complete URL in structured metadata.

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

Can I preserve a fixed filename for the latest screenshot?

Yes, but treat it as a separate convenience copy. Store immutable, uniquely named captures first, then update a deliberately managed latest.png reference.

Frequently Asked Questions

Are UUID filenames cryptographically secure?

UUID4 is designed for practical identifier uniqueness, not as a secret or access-control mechanism. Do not put credentials in filenames.

Should I include the URL in the filename?

Only after sanitizing and truncating it. A short stable label plus UUID4 is safer; retain the complete URL in structured metadata.

Can I preserve a fixed filename for the latest screenshot?

Yes, but treat it as a separate convenience copy. Store immutable, uniquely named captures first, then update a deliberately managed latest.png reference.

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.

The Bottom Line

For Python screenshot jobs, combine a UTC timestamp with uuid4().hex, create the destination directory with Path.mkdir(..., exist_ok=True), and pass that path to Playwright, MSS, or your chosen capture backend.

Quick Recap

Bestseller No. 2
Sandisk 1TB Portable SSD, Up to 800MB/s Read Speeds, Black (Old Model)
Sandisk 1TB Portable SSD, Up to 800MB/s Read Speeds, Black (Old Model)
From Sandisk, a brand professional photographers trust to take on assignments.
$188.90
SaleBestseller No. 4
Sandisk 1TB Extreme Portable SSD, Up to 2000MB/s Transfer Speeds-New Model
Sandisk 1TB Extreme Portable SSD, Up to 2000MB/s Transfer Speeds-New Model
IP65 RATING AND UP TO 3M DROP PROTECTION(3) – protects against spills and drops.; POCKET-SIZED – fits easily in pockets and small bags.
$253.00
SaleBestseller No. 5
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$129.99

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.