Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk8 min

How to Run a Bulk Website Screenshot Job on an Indian Cloud VPS

A practical Python and Playwright workflow for capturing many public URLs from an Indian VPS, with region selection, failure handling, storage, and managed alternatives.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a bounded Playwright worker on a VPS in an Indian region: read URLs from a file, open each page in a controlled browser context, save screenshots under unique names, and record each result. Playwright provides the page-capture primitive; the URL queue, concurrency, retries, and storage are choices you must implement. The example below uses Python and is a starting point, not a tested throughput recipe.

Plan the batch before starting the browser

Decide what a job means before sending it to a worker. A plain-text file with one public URL per line is easy to validate and resume; a CSV is useful if each row also needs an identifier or output options. A sitemap can supply URLs, but you still need to parse it, decide which URLs to include, and handle duplicates.

As an Amazon Associate I earn from qualifying purchases.

Choose inputs and output names

  • Normalize and validate each URL, and decide whether duplicate URLs should produce one capture or multiple records.
  • Use a stable identifier or a URL-derived digest in filenames rather than raw URLs, which can contain characters unsuitable for paths and may expose query values. Keep a separate manifest mapping each input to its output and status.
  • Write each run into its own directory. Persist screenshots and the manifest to durable disk or object storage so a VPS restart does not erase completed work.

Set operating limits

Choose a modest worker count, a navigation timeout, a maximum number of attempts, and a policy for pages that fail. These are application-level decisions: the Playwright screenshot documentation does not prescribe bulk queues, concurrency limits, retry policy, or VPS sizing. Start conservatively, observe resource use and failures on your own URL set, then adjust.

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

Choose an India cloud region carefully

For AWS, the region table lists Asia Pacific (Mumbai), ap-south-1, with opt-in not required, and Asia Pacific (Hyderabad), ap-south-2, with opt-in required. Check the current AWS Regions and Availability Zones table and enable Hyderabad for the account if needed. AWS also advises considering service and feature availability and proximity to most users.

#1 Best Overall
DARGO Mini Server – Plug & Play Home Host with No Monthly Fees. 2GB RAM, 128GB SSD
  • TRUE PLUG-AND-PLAY HOME SERVER: Forget complex VPS setups or command lines. Simply connect power and Ethernet to start hosting immediately with zero technical skills required. This managed, all-in-one appliance is the easiest way to run blogs (compatible with WordPress), private applications, and bots directly from home using your own domain.
  • NO MONTHLY SUBSCRIPTION FEES: Stop renting server space. Enjoy a one-time hardware purchase model with absolutely no recurring hosting fees for typical usage. The system includes a generous monthly traffic allowance that covers the needs of almost all personal and small business websites, allowing the device to pay for itself quickly.
  • INSTANT ONE-CLICK APP LIBRARY: Instantly deploy over 50 curated open-source applications without hassle. The diverse ecosystem includes essential tools, compatible with WordPress, Ghost, Nextcloud (for private cloud storage), Joomla, and OpenClaw. Perfect for content management, e-commerce, private email, and business tools.
  • INCLUDES FREE SSL & ENTERPRISE SECURITY: Get professional performance and safety without the extra costs. Seamlessly integrate your existing custom domain or utilize the included free subdomain. Your sites are automatically secured with free SSL certificates, built-in DDoS protection, and global CDN acceleration.
  • TOTAL DATA PRIVACY & OWNERSHIP: Keep your digital assets secure on your own local hardware, not on third-party "big tech" servers. Designed for privacy-conscious individuals, creators, and small businesses seeking platform independence. Includes an intuitive web management portal for complete peace of mind.

For Azure, the regional geography page lists Central India, South India, West India, and India South Central among regions available or coming soon. It directs customers to check service availability for the region under consideration. A listed cloud region does not prove that the VM family or every dependent service you need is available there; verify the current service matrix before provisioning. See Azure geographies and regional service availability.

The worker’s location determines its network path and may affect how a site is presented. It does not bypass a site’s access controls or grant permission to capture content. Follow the target site’s terms and access rules.

Capture one page with Playwright Python

Install Python and Playwright on the VPS, then install the browser binaries required by Playwright. The official Playwright Python screenshots guide documents saving a page screenshot with page.screenshot(path="screenshot.png") and capturing the full scrollable page with full_page=True. It also covers buffers, locator screenshots, and screenshot format and quality parameters.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
python -m pip install playwright
python -m playwright install chromium

A minimal single-page capture looks like this:

import asyncio
from pathlib import Path
from playwright.async_api import async_playwright

async def main():
    output = Path("screenshots")
    output.mkdir(parents=True, exist_ok=True)

    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto("https://example.com", wait_until="domcontentloaded", timeout=30_000)
        await page.screenshot(path=str(output / "example.png"), full_page=True)
        await browser.close()

asyncio.run(main())

Use a specific wait condition that fits the pages you capture. Waiting for all network activity to stop can be unsuitable for pages with long-lived requests; a page that renders content after initial navigation may need a selector wait or a deliberate delay. Those choices depend on the site and should be tested with representative pages.

Turn the capture into a bounded bulk worker

This runnable example reads one URL per line from urls.txt, limits simultaneous pages with a semaphore, gives each URL a stable filename, records success or failure in JSON Lines, and retries a failed capture a bounded number of times. It launches one Chromium process for the run rather than launching an unbounded browser per URL. It does not deduplicate input rows: repeated URLs are captured separately with row-specific names.

import asyncio
import hashlib
import json
from pathlib import Path
from urllib.parse import urlparse
from playwright.async_api import async_playwright

INPUT = Path("urls.txt")
OUT = Path("run-001")
WORKERS = 3
NAV_TIMEOUT_MS = 30_000
ATTEMPTS = 2  # total attempts per URL


def load_urls(path):
    urls = []
    for line_number, raw in enumerate(path.read_text(encoding="utf-8").splitlines(), 1):
        url = raw.strip()
        if not url or url.startswith("#"):
            continue
        parsed = urlparse(url)
        if parsed.scheme not in ("http", "https") or not parsed.netloc:
            raise ValueError(f"Invalid URL on line {line_number}: {url!r}")
        urls.append((line_number, url))
    return urls


def output_name(line_number, url):
    digest = hashlib.sha256(url.encode("utf-8")).hexdigest()[:12]
    return f"{line_number:06d}-{digest}.png"


async def main():
    OUT.mkdir(parents=True, exist_ok=True)
    urls = load_urls(INPUT)
    semaphore = asyncio.Semaphore(WORKERS)
    log_path = OUT / "results.jsonl"

    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)

        async def capture(line_number, url):
            filename = output_name(line_number, url)
            target = OUT / filename
            async with semaphore:
                for attempt in range(1, ATTEMPTS + 1):
                    page = await browser.new_page()
                    try:
                        response = await page.goto(
                            url,
                            wait_until="domcontentloaded",
                            timeout=NAV_TIMEOUT_MS,
                        )
                        await page.screenshot(path=str(target), full_page=True)
                        return {
                            "line": line_number,
                            "url": url,
                            "status": "ok",
                            "http_status": response.status if response else None,
                            "file": filename,
                            "attempts": attempt,
                        }
                    except Exception as exc:
                        if attempt == ATTEMPTS:
                            return {
                                "line": line_number,
                                "url": url,
                                "status": "error",
                                "error": str(exc),
                                "attempts": attempt,
                            }
                        await asyncio.sleep(attempt)
                    finally:
                        await page.close()

        tasks = [capture(line, url) for line, url in urls]
        try:
            for task in asyncio.as_completed(tasks):
                result = await task
                with log_path.open("a", encoding="utf-8") as log:
                    log.write(json.dumps(result, ensure_ascii=False) + "n")
        finally:
            await browser.close()


if __name__ == "__main__":
    asyncio.run(main())

Save that as bulk_capture.py, put the input URLs in urls.txt, then run python bulk_capture.py. The output directory contains PNG files and a results log. For resumability, read the manifest on startup and skip successful input identifiers; write logs atomically or flush them if the process may be interrupted. For large runs, append results through a single writer rather than opening a file for every completion.

Rank #3
DARGO Mini Server – Plug & Play Home Host with No Monthly Fees. 8GB RAM, 512GB SSD
  • TRUE PLUG-AND-PLAY HOME SERVER: Forget complex VPS setups or command lines. Simply connect power and Ethernet to start hosting immediately with zero technical skills required. This managed, all-in-one appliance is the easiest way to run blogs (compatible with WordPress), private applications, and bots directly from home using your own domain.
  • NO MONTHLY SUBSCRIPTION FEES: Stop renting server space. Enjoy a one-time hardware purchase model with absolutely no recurring hosting fees for typical usage. The system includes a generous monthly traffic allowance that covers the needs of almost all personal and small business websites, allowing the device to pay for itself quickly.
  • INSTANT ONE-CLICK APP LIBRARY: Instantly deploy over 50 curated open-source applications without hassle. The diverse ecosystem includes essential tools, compatible with WordPress, Ghost, Nextcloud (for private cloud storage), Joomla, and OpenClaw. Perfect for content management, e-commerce, private email, and business tools.
  • INCLUDES FREE SSL & ENTERPRISE SECURITY: Get professional performance and safety without the extra costs. Seamlessly integrate your existing custom domain or utilize the included free subdomain. Your sites are automatically secured with free SSL certificates, built-in DDoS protection, and global CDN acceleration.
  • TOTAL DATA PRIVACY & OWNERSHIP: Keep your digital assets secure on your own local hardware, not on third-party "big tech" servers. Designed for privacy-conscious individuals, creators, and small businesses seeking platform independence. Includes an intuitive web management portal for complete peace of mind.

What the worker does not decide for you

  • Duplicates: the example captures duplicate lines separately. If that is not desired, deduplicate after normalization and preserve a mapping from all original rows.
  • Retry classification: it retries any exception twice. A production worker should distinguish transient navigation or infrastructure failures from persistent invalid URLs, access denials, and other failures that will not improve with retries.
  • HTTP outcomes: a page can return an error status and still render a screenshot. Decide whether to keep those screenshots, mark the result separately, or reject them.
  • Full-page size: full-page images can be large or impractical for very long pages. Use viewport screenshots or a targeted locator when the whole document is unnecessary; Playwright documents locator screenshots in its screenshot guide.
  • Durability: this sample writes locally and does not upload to object storage. Add a durable destination and verify uploads before marking work complete if local VPS storage is temporary.

Operational issues, reliability, and cost

Timeouts, dynamic rendering, anti-bot controls, authentication walls, consent prompts, and long pages can change what a capture returns or prevent it from succeeding. Treat these as per-site operational conditions, not guarantees of the screenshot API or browser. Do not evade access controls; capture only pages you are allowed to access.

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

Record the URL, timestamp, attempt count, status, HTTP response status when available, and error message for every item. Keep failures in the manifest rather than silently dropping them. Isolate artifacts by job so a rerun cannot overwrite unrelated output, and use a bounded retry count to prevent a persistent failure from consuming the whole queue.

There is no documented VPS size, throughput benchmark, or recommended concurrency for this workflow in the cited browser and cloud references. Browser memory, page complexity, full-page image dimensions, and the worker count all affect resource use. Estimate capacity with a representative sample, monitor memory, CPU, disk, and network activity, and increase concurrency gradually. Cloud compute and storage costs depend on the provider, region, instance, duration, and artifact retention; the cited sources do not provide comparable prices for this job.

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

When a managed option makes sense

A self-hosted VPS gives you control over browser versions, dependencies, input handling, and where results are written, but you own orchestration and operations. If you want to avoid operating that capture worker, ScreenshotNeo is the first service to try: it removes known consent banners, newsletter popups, and chat widgets before capture, bills only clean shots, and has the lowest paid plan.

AddScreenshots describes asynchronous bulk capture for URL lists, sitemaps, and domains, with images stored in a customer’s cloud repository. Its API reference may be an older-crawled page, so confirm that the endpoint and terms are current before relying on it: AddScreenshots API reference.

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

Microsoft Playwright Workspaces is described as managed cloud browser infrastructure. The cited overview lists Australia East, East Asia, East US, Japan East, Switzerland North, West Europe, and West US 3, but not India. That is a snapshot of the displayed overview, not a guarantee of current or future availability; check the live region information before choosing it for an India-origin workload: Microsoft Playwright Workspaces regions.

Or skip the browser setup

ScreenshotNeo accepts a URL in one GET request and can return an image or PDF. For example, using a JPEG output filename:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.jpg

See the ScreenshotNeo API documentation for request options. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents use screenshot tools, and 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000. Learn about ScreenshotNeo, or sign up for 1,000 free screenshots a month with no card.

Frequently Asked Questions

Can Playwright save screenshots in a format other than PNG?

Yes. The screenshot API accepts format and quality parameters; consult the Playwright screenshot documentation for the supported options.

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

Does placing the VPS in India guarantee that every target site will load?

No. A region determines the worker’s network location, not the site’s access policy or availability.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.