ScreenshotNeo

BlogAI agents

How to Screenshot a Webpage with an AI Agent Using an Indian Residential Proxy

Use Playwright to capture a webpage through an India-targeted residential proxy. Configure the browser, verify its egress location, and save a viewport, full-page, or element screenshot.

By the ScreenshotNeo team4 October 202610 min read

To screenshot a webpage through an Indian residential proxy, configure the proxy when launching a Playwright browser, navigate to the page, confirm the page is in the state you need, and call Playwright’s screenshot API. Verify the observed egress location and inspect the saved image: a provider’s advertised India coverage does not prove that a particular request exited from India or that a site rendered India-specific content.

This approach is useful when an AI agent needs visual evidence of location-dependent public content or rendering. Choose whether to capture the current viewport, the full scrollable page, or one element. Use an accessibility snapshot or locators to understand and operate page controls; use a screenshot to preserve visual appearance. They answer different questions.

1. Choose the capture and the agent workflow

Before writing code, specify what the agent should capture and how it will decide the page is ready. A screenshot taken before a consent dialog, lazy-loaded image, or location-specific component appears may not show the state you intended.

Capture Playwright approach Use it when
Visible viewport page.screenshot() You need the current visible screen at the configured viewport size.
Full scrollable page page.screenshot({ fullPage: true }) You need one image covering the page’s full scrollable height.
One element locator.screenshot() You need a chart, card, banner, or other component rather than the whole page.

For an agent, a useful sequence is: inspect the page structure, find the relevant content or controls, interact if needed, wait for the intended state, then capture. Playwright MCP uses element references from snapshots for interaction. A screenshot preserves visual details such as layout and charts; an accessibility snapshot exposes structured elements that can help an agent find controls. [Playwright accessibility snapshots] [Playwright screenshots]

2. Configure an Indian residential proxy in Playwright

Playwright accepts a proxy configuration when launching a browser. Supply the provider’s current proxy endpoint and credentials through environment variables or a secrets manager. The exact endpoint and account settings depend on the provider and proxy product; do not copy an endpoint from an old example without checking its current setup instructions.

Install Playwright and its Chromium browser in your project using the official instructions: Playwright installation. Save this as screenshot.mjs, then run it with Node.js after setting the required environment variables.

import { chromium } from 'playwright';

const targetUrl = process.env.TARGET_URL;
const proxyServer = process.env.PROXY_SERVER;
const proxyUsername = process.env.PROXY_USERNAME;
const proxyPassword = process.env.PROXY_PASSWORD;

if (!targetUrl || !proxyServer) {
  throw new Error('Set TARGET_URL and PROXY_SERVER before running.');
}

const browser = await chromium.launch({
  proxy: {
    server: proxyServer,
    ...(proxyUsername ? { username: proxyUsername } : {}),
    ...(proxyPassword ? { password: proxyPassword } : {}),
  },
});

try {
  const context = await browser.newContext({
    viewport: { width: 1440, height: 1000 },
    deviceScaleFactor: 1,
  });
  const page = await context.newPage();

  const response = await page.goto(targetUrl, {
    waitUntil: 'domcontentloaded',
    timeout: 60000,
  });
  console.log('HTTP status:', response?.status() ?? 'no main-document response');

  // Replace this with a locator or page-state check for your target.
  await page.locator('body').waitFor({ state: 'visible', timeout: 15000 });
  await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
  await browser.close();
}

Example invocation:

export TARGET_URL='https://example.com/'
export PROXY_SERVER='http://your-provider-endpoint:port'
export PROXY_USERNAME='your-username'
export PROXY_PASSWORD='your-password'
node screenshot.mjs

Use the provider’s documented proxy protocol and endpoint syntax. Some services use credentials that encode country or session settings in the username; that is provider-specific. Keep secrets out of source control, agent prompts, screenshots, command transcripts, and application logs. The researched Bright Data integration example uses server, username, and password fields and says its residential proxy product requires its SSL certificate for end-to-end secure connections to targets. Check its current instructions if you use that service. [Bright Data’s Playwright integration]

3. Verify location, page state, and screenshot output

A successful navigation only shows that the browser obtained a page response; it does not by itself establish the proxy’s observed country or prove the target used location-specific content. Verify the egress location with an appropriate IP/location check, then confirm the target page’s visible result. The Bright Data integration example visits an IP-check endpoint before continuing; treat this as a validation step, not a guarantee about any proxy request. [Bright Data’s Playwright integration]

For location-sensitive captures, record enough non-secret context to reproduce a discrepancy: target URL, capture time, viewport, selected capture scope, observed egress location, navigation status, and relevant page-state checks. Do not log proxy credentials or session tokens.

Wait for the state you need

domcontentloaded waits for the initial document to be parsed but does not guarantee that client-rendered content or images are ready. Prefer a meaningful locator when you know what should appear:

await page.getByRole('heading', { name: 'Expected heading' }).waitFor();

If the page has no stable locator, a short explicit delay can help with a known animation or late update, but delays make runs slower and can still be too short or unnecessarily long. Avoid treating network-idle timing as proof that the content is correct: pages with analytics or polling may keep requests active, and a quiet network does not ensure the right state.

Set image dimensions deliberately

Playwright screenshots are affected by viewport size and device scale factor. A larger device scale factor produces more image pixels for the same CSS viewport, which can help visual inspection but increases output size. If image coordinates must line up with CSS coordinates, choose and record the scale factor rather than assuming pixel dimensions equal CSS dimensions. Playwright documents viewport and screenshot options in its API reference. [Playwright Page screenshot API] [Playwright screenshots]

4. Capture an element or a viewport instead of the full page

Full-page capture is convenient, but it is not always the most useful output. Capture the viewport for a screenshot corresponding to what a visitor currently sees. Capture a specific element when the agent has located the relevant component.

// Viewport image
await page.screenshot({ path: 'viewport.png' });

// One element, found by a selector
await page.locator('[data-testid="price-chart"]').screenshot({
  path: 'chart.png',
});

Selectors are target-specific. Prefer a stable test identifier or accessible locator over a brittle positional selector where possible. If the locator matches no elements, inspect the page state and selector rather than silently saving an unrelated screenshot. Element capture can also fail when the element is detached, hidden, or outside a usable rendered state; wait for the element and confirm it is visible first. [Playwright element screenshots]

5. Use an AI agent with Playwright MCP

Playwright MCP gives an MCP-compatible AI agent browser tools, including page inspection and interaction. The agent can use a snapshot to find an element reference, interact with the page, and then request a screenshot. MCP provides the agent-facing workflow; the proxy still needs to be configured in the browser runtime used for that session. Check the current Playwright MCP documentation for setup and available tools. [Playwright MCP documentation]

When using an MCP server, make the task bounded and specific: give the target URL, define the desired page state, specify viewport or full-page capture, and tell the agent where the output should be saved. Keep proxy secrets in the runtime’s secret configuration rather than in agent-visible instructions. Confirm whether the MCP runtime exposes the proxy launch configuration you need; configuration mechanisms depend on how the server is started.

6. Other runnable options: cURL, Python, and Node.js

Playwright is the practical choice when an AI agent must render and interact with a webpage before capture. cURL and a plain HTTP client do not render a browser screenshot. They can check a proxy connection or fetch HTML, but they do not replace browser automation for visual capture.

cURL: inspect a proxy connection

Use your provider’s proxy URL and an appropriate IP-check endpoint to check observed egress. This is a network validation request, not a screenshot:

curl --proxy "$PROXY_SERVER" \
  --proxy-user "$PROXY_USERNAME:$PROXY_PASSWORD" \
  https://api.ipify.org

Do not paste a credential-bearing proxy URL into shell history or shared logs. Provider-specific authentication, TLS certificates, and endpoint formats vary; follow the provider’s current guidance.

Python: take a screenshot with Playwright

Install the official Python package and browser per the Playwright Python documentation. This example uses the synchronous API:

import os
from playwright.sync_api import sync_playwright

target_url = os.environ["TARGET_URL"]
proxy = {
    "server": os.environ["PROXY_SERVER"],
    "username": os.environ.get("PROXY_USERNAME", ""),
    "password": os.environ.get("PROXY_PASSWORD", ""),
}
proxy = {key: value for key, value in proxy.items() if value}

with sync_playwright() as p:
    browser = p.chromium.launch(proxy=proxy)
    try:
        page = browser.new_page(viewport={"width": 1440, "height": 1000})
        response = page.goto(
            target_url,
            wait_until="domcontentloaded",
            timeout=60_000,
        )
        print("HTTP status:", response.status if response else "no main-document response")
        page.locator("body").wait_for(state="visible", timeout=15_000)
        page.screenshot(path="page.png", full_page=True)
    finally:
        browser.close()

Node.js: take a screenshot with Playwright

The runnable Node.js Playwright example is the code in section 2. For a minimal viewport capture, the core sequence is:

const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
await page.goto(targetUrl, { waitUntil: 'domcontentloaded', timeout: 60000 });
await page.screenshot({ path: 'viewport.png' });

7. Proxy selection, reliability, and cost

Choose a proxy service based on the actual job requirements, not a country-coverage claim alone. Compare the location precision you need, session behavior, proxy protocol, credential handling, certificate requirements, target-site reliability, current price and usage limits, and the provider’s sourcing and access policies. Confirm the egress location against your own request and target. Bright Data is one researched example: its materials advertise India proxies and location-based testing and document a Playwright integration. Those materials do not establish independent service quality, a guaranteed result on a particular site, or legal clearance for every task. Review current provider policies and the target’s requirements. [Bright Data residential proxies] [Bright Data Playwright integration] [Bright Data acceptable use policy]

Proxy charges and limits depend on the provider’s current plan and billing unit. Check traffic billing, concurrency, session controls, trial restrictions, and overage terms before scaling. A residential proxy does not make a request automatically permitted. Use it only for content and access patterns you are authorized to inspect, and follow applicable provider and target-site rules.

For reliability, separate network and page failures in your logs: proxy connection or authentication errors, navigation timeouts, non-success HTTP responses, unexpected page state, and screenshot failures need different fixes. Retry only errors that are likely transient, use a bounded retry policy, and avoid launching unbounded concurrent browsers. Recheck location after changing proxy settings or session behavior.

8. Troubleshooting

Symptom Likely cause What to do
Proxy connection fails before navigation Incorrect endpoint, protocol, port, credentials, or provider access settings. Check the provider’s current endpoint format and account instructions. Validate the proxy separately with a permitted IP-check request.
Authentication or tunnel error Credentials are missing, malformed, expired, or unsupported in the configured form. Confirm the account credentials and whether the provider expects username/password fields or another authentication method. Keep credentials out of logs.
TLS or certificate error The proxy setup requires a provider certificate or a different documented TLS configuration. Follow the provider’s current certificate instructions. Do not disable certificate validation as a workaround.
Page loads, but appears outside India The selected proxy session or endpoint did not produce the expected egress, or the target does not vary content by location. Check observed egress and the target’s rendered content. Review provider location/session settings and repeat with a fresh, documented configuration if appropriate.
Navigation times out Slow target, proxy delay, blocked request, or wait condition unsuitable for the page. Check whether the page responds at all, use a realistic timeout, and wait for a meaningful locator rather than requiring every network request to finish.
Screenshot is blank or incomplete Capture ran before the intended page content appeared, or a script, image, or location check failed. Check the response status and page state, wait for the required content, then inspect the output file and browser errors.
Full-page image is unexpectedly large The page is very tall, has a large viewport scale, or includes long content. Capture a viewport or a specific element if that is sufficient; choose a suitable device scale factor and output format for the downstream use.
Element locator screenshot fails The selector matched nothing, the element is hidden, or it changed during capture. Inspect the current DOM or accessibility snapshot, use a stable locator, and wait for the element to be visible before capturing.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. Its API takes a URL and returns a PNG, JPEG, WebP, or PDF. A single API screenshot request does not provide the Indian residential proxy configuration in the Playwright workflow above; use the browser method when the India egress requirement is essential.

For captures that do not require that proxy setup, one GET request can return a screenshot. See the ScreenshotNeo API documentation for options and parameter details.

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)
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}`);

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and the free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month with no card.

FAQ

Does an Indian residential proxy guarantee that a webpage shows the Indian version?

No. Verify the observed egress location and inspect the rendered page. A target may not vary by location, and proxy coverage claims alone do not prove the route taken by a particular request.

Should an AI agent use a screenshot or an accessibility snapshot?

Use a snapshot to discover structured page elements and controls; use a screenshot when the agent needs visual evidence of layout, graphics, or appearance. A workflow may use both.

Can cURL take a webpage screenshot through a proxy?

cURL can send HTTP requests through a proxy, but it does not render a browser screenshot. Use Playwright for browser rendering and capture.