ScreenshotNeo

BlogHow-to

How to Compare Google SERP Screenshots Week over Week

Capture the same Google query under consistent conditions, compare visible SERP changes, and use Search Console separately to check performance trends.

By the ScreenshotNeo team4 October 202611 min read

To compare Google SERP screenshots week over week, capture the exact same query under the same conditions in both weeks, record the context for each capture, and compare visible results and SERP features separately from site performance metrics. A screenshot is an observation of one search under one set of conditions, not proof of a universal ranking: Google says results vary with time, place, device, and recent search history. Google Search Console’s Performance report overview describes those factors and the report’s performance metrics.

Use screenshots to answer “What was visible in this captured SERP?” Use Search Console to answer “How did clicks, impressions, CTR, and average position change for my property?” Neither view replaces the other.

1. Set up a repeatable comparison

  1. Choose a fixed query set. Store the exact query text, including spelling and punctuation. Record the audience and intended location for each query.
  2. Fix the search context. Keep country or location, language, device, viewport, browser zoom, browser/search state, and approximate capture time consistent. Record the date, time, and time zone. These are practical controls based on Google’s description of result variability, not a Google-published screenshot protocol.
  3. Choose and document the capture depth. Use full-page captures, or use the same viewport and documented scroll depth each week. Preserve enough of the page to identify the query and capture date in your accompanying notes.
  4. Repeat at comparable times. For manual captures, aim for the same weekday and approximate time. If the timing differs, record the mismatch as a limitation. For longer-range Search Console trends, Google recommends weekly or monthly aggregation to reduce day-of-week effects in date comparisons; that recommendation concerns performance comparisons, not screenshot collection. See Search Console’s comparison guidance.
  5. Save the originals and a log. Use filenames that include the query identifier and capture date. Keep the original images alongside any annotated copies so observations can be checked against the source captures.

Capture log template

query_id,query,captured_at,time_zone,country_or_location,language,device,viewport,browser_state,capture_depth,target_url,visible_position,features,observed_differences,context_notes

Write observations such as “the target URL appeared below the image module in these captures.” Avoid turning one pair of screenshots into a claim that Google changed rankings everywhere.

2. Capture the same SERP with a browser

A browser automation script can make viewport, locale, and timing easier to repeat. The following Python example uses Playwright to open Google’s search URL, save a full-page screenshot, and record the run context. Install Playwright and its Chromium browser first:

python -m pip install playwright
python -m playwright install chromium
import asyncio
import csv
import os
from datetime import datetime, timezone
from urllib.parse import urlencode
from playwright.async_api import async_playwright

QUERY = "example search query"
COUNTRY = "us"
LANGUAGE = "en"
WIDTH = 1365
HEIGHT = 900
OUT_DIR = "serp-captures"
os.makedirs(OUT_DIR, exist_ok=True)

async def main():
    now = datetime.now(timezone.utc)
    stamp = now.strftime("%Y-%m-%dT%H-%M-%SZ")
    params = urlencode({"q": QUERY, "gl": COUNTRY, "hl": LANGUAGE})
    url = f"https://www.google.com/search?{params}"

    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        context = await browser.new_context(
            viewport={"width": WIDTH, "height": HEIGHT},
            locale=LANGUAGE,
            timezone_id="UTC",
            device_scale_factor=1,
        )
        page = await context.new_page()
        response = await page.goto(url, wait_until="domcontentloaded", timeout=60000)
        await page.wait_for_timeout(2500)
        path = os.path.join(OUT_DIR, f"serp-{stamp}.png")
        await page.screenshot(path=path, full_page=True)

        with open(os.path.join(OUT_DIR, "captures.csv"), "a", newline="", encoding="utf-8") as f:
            writer = csv.writer(f)
            writer.writerow([
                QUERY, now.isoformat(), "UTC", COUNTRY, LANGUAGE,
                f"{WIDTH}x{HEIGHT}", "Chromium headless", "full page",
                response.status if response else "no response status", path
            ])
        await browser.close()

asyncio.run(main())

This is a browser-capture example, not a guarantee that Google will return identical results on every run. Search state, location interpretation, consent flows, serving changes, and automated-access checks can affect what loads. Use a permitted, consistent capture method and retain the status and context rather than silently treating a failed or blocked navigation as a valid SERP.

cURL: retrieve an already saved capture

cURL can download a screenshot file from storage or a URL your own capture system exposes. It does not render a live Google results page by itself.

curl --fail --location "https://example.com/serp-captures/serp-2026-10-04.png" --output serp-2026-10-04.png

Node.js: capture with Playwright

Install Playwright and Chromium with npm install playwright and npx playwright install chromium, then run:

const { chromium } = require('playwright');
const fs = require('node:fs/promises');

(async () => {
  const query = 'example search query';
  const country = 'us';
  const language = 'en';
  const width = 1365;
  const height = 900;
  const stamp = new Date().toISOString().replaceAll(':', '-');
  const url = new URL('https://www.google.com/search');
  url.search = new URLSearchParams({ q: query, gl: country, hl: language }).toString();

  const browser = await chromium.launch({ headless: true });
  try {
    const context = await browser.newContext({
      viewport: { width, height },
      locale: language,
      timezoneId: 'UTC',
      deviceScaleFactor: 1,
    });
    const page = await context.newPage();
    const response = await page.goto(url.toString(), {
      waitUntil: 'domcontentloaded',
      timeout: 60000,
    });
    await page.waitForTimeout(2500);
    await fs.mkdir('serp-captures', { recursive: true });
    await page.screenshot({ path: `serp-captures/serp-${stamp}.png`, fullPage: true });
    console.log(JSON.stringify({
      query, capturedAt: new Date().toISOString(), country, language,
      viewport: `${width}x${height}`, status: response?.status() ?? null,
    }));
  } finally {
    await browser.close();
  }
})().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

3. Compare the screenshots systematically

  1. Confirm that the query, location, language, device, viewport, browser state, and capture depth match. Flag mismatches before interpreting visual changes.
  2. Compare the page from top to bottom. Note visible result order, titles, URLs, snippets, and SERP modules such as local, image, or video results.
  3. Record which modules appeared, disappeared, changed order, or moved into or out of the captured viewport.
  4. For each target URL, record whether it is visible and its position among the visible results. Say “visible position in this capture,” not “the rank,” if the screenshot does not show the whole page or the context differs.
  5. Separate layout or module changes from organic listing changes. A changed module can push results lower in the viewport even if their order relative to each other is unchanged.
  6. Write the first changed item and the evidence for it in the log. Preserve the two captures and annotate copies if a visual diff helps reviewers.
Axis What to record Why it matters
Query Exact query string A wording change can produce a different results page.
Time Date, time, time zone, weekday Results and performance can vary over time; weekday mismatch limits trend comparisons.
Place and language Country or location and language Geographic and language context can change visible results.
Device and viewport Device type, viewport dimensions, zoom, scale Layout and the portion of the page in view can differ.
Browser/search state Browser, signed-in state if applicable, cookies or other relevant state Recent search history and browser state may affect the observation.
Visible content Result order, titles, URLs, snippets, modules, target URL position These are the features the screenshot can directly support.
Capture scope Full page or viewport and scroll depth Different page depth can make features appear to have entered or left the SERP.

4. Check performance in Search Console separately

Open the Search results Performance report and compare aligned date ranges. Use the same search type and dimensions in both periods unless the dimension itself is what you are investigating. The report supports filters and dimensions including query, page, and country, and reports clicks, impressions, average CTR, and average position. Consult the Performance report overview for the available report controls.

For comparisons across weeks, align equivalent weekdays where possible or use weekly aggregation for longer windows. Search Console’s comparison guidance notes that weekly or monthly aggregation can reduce day-of-week effects. It also cautions that some metric calculations can change when comparing dimensions such as page or search appearance, so keep selections stable and record any changes. Search Console displays data in the browser’s time zone while the underlying data remains the same; note that displayed time zone when reconciling dates with screenshot timestamps. See Google’s note on the recent performance data view.

Average position is an aggregate: Google describes it as the position of the topmost result from the site, and multiple results from the same site can count as one impression in the chart. It is not the fixed rank of a URL for every search or the exact position in one screenshot. Use the screenshot for the visible SERP, and Search Console for property-level performance trends.

5. Interpret changes with care

A visual difference can come from a changed search context, SERP composition, or ranking and serving changes. Google says its ranking and serving systems are continually updated, and core updates can affect how pages perform. Include update start and completion dates in the comparison log. Google recommends waiting at least a full week after a core update completes before analyzing site performance in Search Console, and notes that positions are not static. See Google’s core updates guidance.

If traffic changed, use the Search Console date comparison to find affected queries and pages, then consider broader interest and other causes. Google’s traffic-drop guidance recommends investigating affected queries with Performance report filters, checking Google Trends for broader interest changes, and comparing date ranges. A screenshot cannot show clicks or impressions; a performance chart cannot show exactly which modules appeared in an individual captured SERP.

6. Troubleshooting

Symptom Likely cause Fix
One capture shows a consent, verification, or unusual interstitial page The navigation did not reach the results page or an automated-access check intervened. Mark the capture as blocked or invalid, preserve its status and notes, and retry using a permitted method. Do not compare it as a SERP.
The screenshots look different despite using the same query Location, time, device, viewport, browser/search state, or page depth differed; results also change over time. Compare the recorded context first. Repeat under matched conditions where possible and report remaining differences as limitations.
A result seems to move down, but its relative order is unchanged A SERP feature or layout change occupies more space above it. Log module position and organic order separately. Note whether the comparison uses a full page or fixed viewport.
The script times out or saves a blank page Navigation was slow, interrupted, or did not produce usable content before the timeout. Check the response status and saved page state, increase the timeout if appropriate, wait for the page to settle, and capture again. Treat blank or incomplete output as a failed capture.
Search Console dates do not line up with screenshot dates The report uses the browser time zone, or the periods and aggregation differ. Record the displayed time zone, align the date ranges, and keep granularity and dimensions consistent.
Average position changes but the screenshot does not show a matching movement Average position aggregates property results across impressions and is not a fixed rank for one search context. Inspect query and page filters and use the screenshot only as evidence about its captured SERP.
A period overlaps a Google core update The systems may be changing during the comparison window. Annotate update dates and avoid drawing a firm performance conclusion until at least a full week after the update completes, following Google’s guidance.

7. Performance, reliability, and cost

For a small query set, a manual weekly capture and a short log may be enough. For repeated captures, automate the same query-context matrix and store images with timestamps and metadata together. Run captures at a consistent cadence, preserve failed-run records, and retry failures with a limit so a transient issue does not silently remove a week from the comparison. Avoid interpreting retries at a different time as if they were taken at the scheduled time.

Full-page screenshots can be larger and slower to save than viewport captures, and long pages can include content that was outside the initially visible area. Use the same capture scope each week. Keep original images for auditability and use compressed or resized derivatives only for sharing. Browser automation has infrastructure costs in runtime and storage; estimate them from your own query count, capture frequency, retention period, and image sizes rather than assuming a universal cost.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request can return a screenshot or PDF; its capture options include full-page screenshots with lazy images loaded, device and viewport settings, custom CSS and JavaScript, selectors, waits, headers, cookies, user agents, and caching. For SERP comparison, use consistent parameters and save the capture time and context alongside each response. See the ScreenshotNeo API documentation for parameter details.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://www.google.com/search?q=example+search+query&gl=us&hl=en -o serp.webp
import requests

params = {
    "access_key": "YOUR_API_KEY",
    "url": "https://www.google.com/search?q=example+search+query&gl=us&hl=en",
    "full_page": "true",
    "format": "webp",
}
r = requests.get("https://api.screenshotneo.com/v1/shot", params=params, timeout=90)
r.raise_for_status()
open("serp.webp", "wb").write(r.content)
print("Page verdict:", r.headers.get("X-Page-Verdict"))
print("Billed:", r.headers.get("X-Billed"))
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://www.google.com/search?q=example+search+query&gl=us&hl=en',
  full_page: 'true',
  format: 'webp',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('serp.webp', Buffer.from(await res.arrayBuffer()));
console.log('Page verdict:', res.headers.get('X-Page-Verdict'));
console.log('Billed:', res.headers.get('X-Billed'));

ScreenshotNeo removes known consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers report the page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. These captures remain observations under their recorded conditions, so retain query, time, location, language, and viewport metadata for a fair comparison.

Sign up for 1,000 free screenshots a month with no card.

FAQ

Does a screenshot prove my Google ranking?

No. It records what was visible for one query and one search context. Use Search Console for aggregate property performance and keep the capture context with the image.

Should I compare the same weekday?

That is a useful control for both capture scheduling and performance comparisons. Google specifically recommends weekly or monthly aggregation to reduce weekday effects in Search Console comparisons; matching screenshot weekdays is a practical method, not a Google screenshot rule.

Can I use Search Console instead of keeping screenshots?

No. Its Performance report provides metrics and dimensions, while screenshots preserve the visible layout and modules of a captured results page.