How to Schedule Daily Screenshots of an Indian Ecommerce Product Page
Use Playwright with GitHub Actions to capture an Indian ecommerce product page every day, save dated screenshots, and handle scheduling limits and failures.
To schedule a daily screenshot of an Indian ecommerce product page, use a browser automation tool such as Playwright to capture the page and a scheduler such as GitHub Actions to run that script each day. The example below captures a full-page PNG, names it with the India-local date, and uploads it as a workflow artifact. GitHub Actions schedules use UTC by default, but can specify an IANA timezone such as Asia/Kolkata. [Playwright screenshots] [GitHub Actions schedule event]
1. Choose what the screenshot should show
Before automating, decide whether you need the visible browser viewport, the entire scrollable page, or one stable element such as the product image and price panel. Playwright supports all three. A full-page capture can include long descriptions and recommendations; a viewport capture is smaller and easier to compare; an element capture narrows the image to a component. Keep the capture type, viewport, browser, and other relevant conditions the same on every run if you plan to compare screenshots over time. [Playwright screenshot options]
Use the exact product URL, including any required variant or region parameters. Ecommerce pages may show different prices, availability, or content based on location, account state, cookies, or selected options. This workflow records what its browser receives; it does not guarantee that the page represents every shopper’s view.
2. Create a runnable Playwright capture script
This example uses Node.js, Playwright, and GitHub Actions. It opens the product page, waits for a product heading, and saves a full-page PNG with the date in the Asia/Kolkata timezone. Change the URL and selector to match the page. The product heading is a sample wait target, not a selector guaranteed to exist on any particular retailer.
// screenshot.mjs
import { chromium } from 'playwright';
const productUrl = process.env.PRODUCT_URL;
if (!productUrl) throw new Error('Set PRODUCT_URL to the exact product page URL');
const browser = await chromium.launch({ headless: true });
try {
const page = await browser.newPage({
viewport: { width: 1440, height: 1000 },
deviceScaleFactor: 1
});
await page.goto(productUrl, { waitUntil: 'domcontentloaded', timeout: 60000 });
// Replace this with a stable selector on the target product page.
await page.locator('h1').first().waitFor({ state: 'visible', timeout: 30000 });
await page.screenshot({ path: 'screenshots/product.png', fullPage: true });
} finally {
await browser.close();
}
Set up the project locally with Node.js installed:
mkdir -p screenshots
npm init -y
npm install --save-dev playwright
npx playwright install chromium
node screenshot.mjs
For a selected element, replace the screenshot line with await page.locator('[data-testid="price-panel"]').screenshot({ path: 'screenshots/price.png' }) and use a selector that the page actually exposes. For the visible viewport, omit fullPage: true. Playwright can also return screenshot bytes instead of writing a file, which is useful when uploading directly to storage. [Playwright screenshots]
3. Run it once a day with GitHub Actions
Add this workflow as .github/workflows/daily-screenshot.yml. The cron below means 03:30 India Standard Time: India is UTC+05:30, so 03:30 IST is 22:00 UTC on the preceding day. The workflow specifies Asia/Kolkata explicitly and uses the UTC expression as a fallback for older GitHub Enterprise Server versions that do not support timezone scheduling. Check the workflow event reference for current syntax and platform behavior. [GitHub Actions schedule event]
name: Daily product screenshot
on:
schedule:
- cron: '0 22 * * *'
timezone: 'Asia/Kolkata'
workflow_dispatch:
permissions:
contents: read
jobs:
capture:
runs-on: ubuntu-latest
timeout-minutes: 10
env:
PRODUCT_URL: ${{ secrets.PRODUCT_URL }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: mkdir -p screenshots
- run: node screenshot.mjs
- uses: actions/upload-artifact@v4
with:
name: product-screenshot-${{ github.run_id }}
path: screenshots/*.png
if-no-files-found: error
retention-days: 30
Put the product URL in the repository’s Actions secret named PRODUCT_URL instead of committing a URL containing private query parameters or credentials. The artifact retention setting is an example: choose a duration that fits your recordkeeping needs and your repository plan. An uploaded artifact is not a permanent archive. If you need longer retention, decide on a storage destination and lifecycle policy separately.
Run the workflow once with Run workflow to check configuration, then confirm scheduled runs appear in the Actions tab. GitHub notes scheduled workflows can be delayed during periods of high load, particularly near the start of an hour, and sufficiently high load can cause queued scheduled jobs to be dropped. A daily Actions schedule is therefore suitable when some timing variation is acceptable; do not rely on it as an exact-time capture guarantee. [GitHub Actions schedule event]
4. Configure the capture for meaningful daily comparisons
| Choice | Use it when | Trade-off |
|---|---|---|
| Viewport screenshot | You track the first screen or a compact page state | Content below the fold is absent |
| Full-page screenshot | You need the full scrollable listing or description | Long pages create larger images and can contain changing recommendations or footers |
| Element screenshot | You care about a specific image, price, or availability block | Selectors can break when a site changes its markup |
Set a fixed viewport and use the same capture mode each run. Wait for a page-specific signal, such as a product title or price panel, rather than assuming that a fixed delay always means the page is ready. If images load lazily as the page scrolls, a full-page screenshot can trigger their loading; for pages that still omit images, tailor the script to scroll through the page and wait for relevant image elements to finish loading. Avoid adding a long fixed sleep without a reason: it increases runtime and still cannot ensure content is ready.
The example stores one artifact per run. For a historical series, use a storage location and naming scheme that preserves each date, for example product-2026-10-04.png. For multiple products, keep a list of URLs and create a separate capture per URL, with clear names and failure handling so one broken page does not silently hide the others.
5. When a managed AWS canary fits better
If your monitoring already runs in AWS, CloudWatch Synthetics is another way to run scheduled browser canaries and store screenshots. AWS documents cron and rate expressions for canary scheduling, browser automation support in Node.js and Python runtimes, and examples that navigate to a page and save a screenshot. Check current AWS pricing and configuration for your region and usage before adopting it; the research sources do not establish a direct cost comparison with GitHub Actions. [CloudWatch Synthetics canaries] [CloudWatch Synthetics runtime library]
Compare schedulers on timezone handling, tolerance for delayed or missed runs, browser flexibility, alerting, retention, and cost. The scheduler triggers the capture; the browser automation performs it. Neither GitHub Actions nor a scheduled canary establishes that a particular retailer permits repeated automated access. Check the target site’s current terms, access controls, and technical restrictions before running the job.
6. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| No scheduled run at the expected India time | Cron interpreted in UTC, missing timezone support, or scheduler delay | Confirm Asia/Kolkata is set and verify the UTC conversion. Check the Actions run history; schedule events can be delayed or dropped during high load. |
PRODUCT_URL is empty |
The Actions secret is missing or named differently | Add the PRODUCT_URL secret in repository settings and ensure the workflow references the same name. |
Timeout while navigating or waiting for h1 |
Slow page, changed markup, blocked request, or no visible heading | Check the URL and selector, increase the timeout only if the page needs it, and capture a diagnostic screenshot or page error in a manual run. |
| Browser executable missing | Playwright package installed without its Chromium browser in the runner | Keep the browser installation step, such as npx playwright install --with-deps chromium. |
| Screenshot is blank or incomplete | Content has not rendered, a consent overlay obscures it, or lazy content has not loaded | Wait for a meaningful selector, inspect the saved image, and add page-specific scrolling or readiness checks where needed. |
| Artifact upload says no files found | Capture failed before writing, or output path differs from workflow path | Ensure the script creates screenshots/ and writes a PNG there; keep if-no-files-found: error so failures are visible. |
| Images differ each day without a product change | Viewport, personalization, rotating promotions, fonts, or recommendations vary | Keep browser settings fixed, use an element capture for the relevant product area, and treat dynamic page regions separately. |
7. Performance, reliability, and cost
A once-daily capture has low volume, but each run still downloads the page and launches a browser. Full-page shots and pages with many images take more time and produce larger files than a small element capture. Use one browser session per run, close it in a finally block, and wait only for the content you need. For many URLs, account for concurrent browser memory and the target site’s request limits. Keep secrets out of source control and restrict workflow permissions to what the job needs.
Reliability depends on both halves of the workflow: the scheduler must start the job, and the page must load in a state suitable for capture. GitHub’s scheduled events have documented delay and drop caveats, while selectors can change as retailers update their pages. Review failed runs and retain artifacts for a deliberate period. If a missed exact-time sample has operational consequences, choose a scheduler whose timing guarantees meet that need and validate those guarantees from current documentation.
The examples use GitHub-hosted workflow minutes and artifacts; their availability, quotas, retention, and any charges depend on the account and current GitHub terms. CloudWatch Synthetics can incur AWS charges. Check current provider pricing for your account and region rather than assuming either option is free or comparing costs from this guide.
8. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. One GET request returns an image or PDF, so a daily scheduler only needs to call the endpoint and save the response. The API documentation lists the supported parameters.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Replace the example URL with the product page you are allowed to capture. Put the API key in your scheduler’s secret store. You can run the same request from Python:
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)
And from 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}`);
- Cookie banners are accepted and removed before the capture; known consent platforms, newsletter popups, and chat widgets can be removed, with each step configurable.
- Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers identify the page verdict and whether the shot was billed.
- An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.
- The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Every feature is on every plan.
Sign up free for 1,000 screenshots a month, no card required.
FAQ
Does this prove what every shopper in India sees?
No. It records one browser session at one URL and time. Location, account state, cookies, product variant, and retailer-side experiments can change the result.
Can I keep screenshots permanently as GitHub artifacts?
Artifact retention is configurable within the service’s current limits. For a longer archive, select separate storage and lifecycle rules.
Can I run the capture from a laptop instead?
Yes. Run the Playwright script manually with PRODUCT_URL set. The scheduled workflow simply automates that invocation.
Is a daily schedule an uptime monitor?
It can reveal a captured page state, but this example does not define alerting or an availability guarantee. Add monitoring and alert behavior if you need operational notification.


