ScreenshotNeo

BlogHow-to

How to Schedule Recurring Website Screenshots with VisualScraper

A cautious workflow for recurring screenshots with VisualScraper, plus a self-managed Python scheduler and a ScreenshotNeo API option.

By the ScreenshotNeo team4 October 20269 min read

Short answer: First confirm that your current VisualScraper account and version support recurring screenshot tasks. The available evidence for this feature is a recent third-party review, not current VisualScraper documentation, so exact interface steps, recurrence limits, timezone behavior, and delivery options cannot be verified here. If recurring captures are available, define the pages and capture scope, choose a cadence, run and inspect a manual capture, then enable the schedule and check a later result.

A recurring screenshot archive gives you a record to review. It does not automatically mean the service detects changes or sends alerts. Verify those separately if you need notifications.

What is known about VisualScraper

A 2026 third-party review describes VisualScraper as an image-scraping tool and reports task scheduling, CSV/JSON/XML export, and email or FTP delivery. This is secondary reporting and may be out of date; it does not establish current availability or document the current interface. Check VisualScraper’s current vendor instructions before relying on any of those features.

In particular, do not assume that VisualScraper offers a particular schedule frequency, timezone selector, screenshot archive, alerting, or cron syntax. The workflow below describes decisions to make in a scheduler that supports recurring captures; it is not a set of verified VisualScraper menu instructions.

Plan the recurring capture

  1. Confirm support. Check the current product documentation or account interface for recurring website screenshot tasks, plan limits, and supported destinations. If the feature is not available, use a scheduler you control, as shown below.
  2. List the target pages. Use the complete page URL for each capture. Decide whether you need a single viewport or the whole page, if the capture service provides that choice.
  3. Choose the purpose. A dated archive is useful for records and later visual review. If you need a notification when a page changes, confirm that the service explicitly supports change detection and alerts.
  4. Set a sensible cadence. Capture often enough to match how quickly the page can change. More frequent jobs use more service capacity or quota; exact costs and limits depend on the selected product and are not verified for VisualScraper here.
  5. Check time settings. If the scheduler shows a timezone or next-run time, confirm both. Do not assume how VisualScraper interprets recurrence times without current product documentation.
  6. Run one capture manually. Inspect the output before scheduling. Check that the correct page loaded, the capture scope is useful, and any required consent, login, or page state is handled.
  7. Enable the recurring task. Confirm that it is active, note the next run, and inspect a later capture. If alerts matter, verify a real alert delivery as a separate step.

Decisions to verify before relying on a schedule

Decision What to check Why it matters
Schedule frequency Available recurrence intervals and any task or monthly limits These determine how often the archive updates and what capacity it consumes.
Timezone Whether schedules use an account timezone, a selected timezone, or another rule A time interpreted in the wrong timezone can run hours away from the intended time.
Capture scope Viewport, full page, or element capture options, if offered The wrong scope can omit content or produce unnecessarily large captures.
Page state Authentication, consent banners, dynamic content, and load timing A repeatable schedule still produces poor records if the page is not in the expected state.
Storage and export Retention, supported formats, destinations, and download process A schedule is only useful if you can retrieve and compare its results later.
Change alerts Whether visual or content change detection exists and where alerts are sent A screenshot archive alone does not imply monitoring or notifications.
Failure behavior Retries, timeouts, job history, and notifications for failed runs Missed runs can leave gaps in a record without being obvious.

Self-managed option: Python, Playwright, and cron

If VisualScraper does not provide the recurrence controls you need, you can capture with a browser script and let your operating system run it on a schedule. This example uses Python and Playwright to save a full-page PNG. It keeps the browser setup in your environment, so you are responsible for browser installation, storage, monitoring, and any page-specific authentication.

1. Install the browser automation package

python -m venv .venv
. .venv/bin/activate
python -m pip install playwright
python -m playwright install chromium

On Windows PowerShell, activate the environment with .venv\\Scripts\\Activate.ps1. Install Chromium with the same python -m playwright install chromium command.

2. Save a capture script

Create capture.py and replace TARGET_URL with the page you are authorized to capture. The script creates a dated PNG filename, waits for the page’s load event, then waits briefly for client-rendered content before taking a full-page screenshot.

from datetime import datetime, timezone
from pathlib import Path
from urllib.parse import urlparse

from playwright.sync_api import sync_playwright

TARGET_URL = "https://example.com/"
OUTPUT_DIR = Path("captures")
NAVIGATION_TIMEOUT_MS = 45_000
SETTLE_TIME_MS = 1_500


def main():
    parsed = urlparse(TARGET_URL)
    if parsed.scheme not in {"http", "https"} or not parsed.netloc:
        raise ValueError("TARGET_URL must be a complete http:// or https:// URL")

    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
    output_path = OUTPUT_DIR / f"capture-{timestamp}.png"

    with sync_playwright() as playwright:
        browser = playwright.chromium.launch(headless=True)
        page = browser.new_page(viewport={"width": 1440, "height": 900}, device_scale_factor=1)
        page.set_default_navigation_timeout(NAVIGATION_TIMEOUT_MS)

        try:
            response = page.goto(TARGET_URL, wait_until="load")
            if response is not None and response.status >= 400:
                raise RuntimeError(f"Page returned HTTP {response.status}: {TARGET_URL}")

            page.wait_for_timeout(SETTLE_TIME_MS)
            page.screenshot(path=str(output_path), full_page=True, animations="disabled")
            print(f"Saved {output_path}")
        finally:
            browser.close()


if __name__ == "__main__":
    main()

Run it once from the project directory before scheduling:

.venv/bin/python capture.py

On Windows, run .venv\\Scripts\\python.exe capture.py. Open the saved image and confirm that the page content and capture scope are right.

3. Schedule repeated runs with cron

For example, to run every day at 09:00 UTC, add a cron entry using the absolute paths to your project and Python executable:

0 9 * * * cd /path/to/project && /path/to/project/.venv/bin/python /path/to/project/capture.py >> /path/to/project/capture.log 2>&1

Cron commonly uses the host’s configured timezone. Confirm the machine timezone and the cron implementation’s behavior before relying on the displayed hour. This example is for a machine you manage; it is not VisualScraper syntax. To change the cadence, update the cron expression according to the scheduler’s documentation. Keep the output and log paths on storage with enough available space.

Browser capture settings and edge cases

  • Full page versus viewport: full_page=True captures the full document as one image. Very long pages can create large images; use full_page=False for only the visible viewport.
  • Wait conditions: wait_until="load" waits for the page load event. Sites that render content afterward may need a selector wait, a longer settling delay, or a site-specific readiness check. A fixed delay is simple but can waste time or still be too short.
  • Lazy-loaded content: Full-page capture does not guarantee every site’s lazy-loaded media has been requested. For such pages, scroll through the page or wait for a known element before capture, then verify the image.
  • Authentication: This sample starts a fresh browser context and does not log in. Do not put credentials directly in source code. For an authenticated page, use a carefully managed browser storage state or a login flow, and protect that state file as a secret.
  • Consent and overlays: Cookie banners, chat panels, or newsletter popups may cover content. This example does not dismiss or remove them. Handle them only where permitted and verify the resulting capture.
  • Dynamic pages: Ads, rotating content, timestamps, and personalization can make two captures differ even when the underlying page has not meaningfully changed.
  • HTTP errors: The script treats a returned status of 400 or higher as a failed run. Some sites return a successful status with an error page, so inspect captures and logs rather than relying on status alone.

Or skip the browser setup

ScreenshotNeo provides a website screenshot API: one GET request returns an image or PDF. The API base is https://api.screenshotneo.com/v1/shot. This example saves a WebP capture; see the ScreenshotNeo API documentation for request options.

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,
)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const bytes = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));

To make recurring captures, call the endpoint from a scheduler you control or use ScreenshotNeo’s other documented scheduling-related integration options as applicable; the one-call example itself is a single capture. 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 take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. See ScreenshotNeo, then sign up for 1,000 free screenshots a month with no card.

Troubleshooting recurring screenshot jobs

Symptom Likely cause What to do
No recurring option is visible The account, plan, or current product version may not support it, or the option may have moved. Check current VisualScraper vendor instructions and account limits. Do not infer support from an old review.
The task runs at the wrong time Timezone or daylight-saving behavior differs from your expectation. Check the configured timezone, next-run display, and host timezone if self-scheduling.
The image is blank or incomplete The page may render after the chosen wait condition, or navigation may have failed. Inspect run history and logs; wait for a page-specific selector or adjust the wait, then rerun manually.
Content is hidden behind a banner or widget The capture includes the page’s current overlays. Use a supported consent or element-handling option if the service provides one, or handle the state in your own script where permitted.
Images are missing on a long page Media may load only when scrolled into view. Use a service with lazy-load handling or add a scroll-and-wait step, then inspect the result.
Runs stop after working initially Credentials expired, quota was reached, the machine was offline, or a job failed without a retry. Review job history and account limits. For cron, confirm the machine was on and inspect the redirected log.
The archive contains duplicate-looking but different images Dynamic elements such as ads, timestamps, or personalized content changed. Capture a stable region or page state, and avoid treating every pixel difference as a meaningful change.
No alert arrives after a page changes Recurring capture may only save snapshots; alerts require separate change detection and notification support. Verify that the product offers change alerts and that the destination is configured and working.

Performance, reliability, and cost

  • Frequency drives workload. More target URLs and more frequent runs increase browser time, storage use, and service quota consumption. Estimate the total runs per month before selecting a schedule.
  • Full-page images cost more to process and store. Use viewport capture when it answers the monitoring question; use full-page capture when below-the-fold content matters.
  • Schedule for the page’s update rate. A very frequent schedule can generate redundant captures. A sparse schedule can miss short-lived changes.
  • Plan for missed runs. Hosted products and self-managed cron jobs have different retry and uptime behavior. Check job history, error notifications, and the last successful capture.
  • Manage retention. A recurring archive grows over time. Decide how long images must be kept and whether they need export or off-machine storage.
  • Measure useful output, not just successful requests. A request can complete while producing a page in the wrong state. Review sample captures and periodically inspect later results.

Frequently asked questions

Does VisualScraper definitely support recurring website screenshots?

A third-party review reports task scheduling, but current first-party documentation was not available in the research for this article. Verify the feature in VisualScraper’s current instructions or account before depending on it.

Does a screenshot archive notify me when a page changes?

No such behavior follows from recurring capture alone. Look specifically for change detection and configured alert destinations.

Should I schedule screenshots in UTC or local time?

Use the timezone that matches the operational requirement, then verify how the chosen scheduler interprets it and what happens at daylight-saving changes.

Can I capture pages that require signing in?

Only if the chosen service or your own browser automation can handle authentication securely. The Python example above does not sign in.

How do I know the schedule is working?

Confirm the task is active, check its next run or job history, and inspect a later image. If missing runs matter, configure and verify failure notifications where available.