ScreenshotNeo

BlogHow-to

How to Capture an Indian Web Page with Selenium After OTP Login

Complete an authorized OTP login, wait for the protected page to render, and capture its viewport with Selenium in Python. Includes troubleshooting and a screenshot API option.

By the ScreenshotNeo team4 October 20266 min read

To capture a page after OTP login, complete the website’s normal one-time password challenge in the same Selenium-controlled browser session, wait for a page-specific sign that the authenticated content is ready, and call driver.save_screenshot("authenticated-page.png"). The example below uses Python and Chrome. Adapt the URL and selectors to a site you are authorized to access; Selenium does not bypass OTP, and Indian websites do not all use the same login flow.

1. Install Selenium and prepare a browser

Use a supported local Chrome installation and a current Selenium Python package. Selenium Manager can assist with driver management when you create a driver with webdriver.Chrome(); if your environment manages browser drivers separately, follow that environment’s setup. This example writes a PNG to the current working directory.

python -m pip install selenium

2. Log in, wait for the authenticated page, and capture it

Replace the example URL and the final page selector with values from the site. Complete the OTP challenge through the site’s ordinary flow. For an out-of-band code, enter it yourself when prompted; avoid hard-coding codes or storing them in source control. The script waits for an expected page heading rather than assuming that a redirect or document load means the page is ready.

from pathlib import Path

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

TARGET_URL = "https://authorized.example/"
OUTPUT = Path("authenticated-page.png")

options = webdriver.ChromeOptions()
options.add_argument("--window-size=1440,1000")

driver = webdriver.Chrome(options=options)
try:
    driver.get(TARGET_URL)

    # Complete the site's normal username/password and OTP steps here.
    # If needed, pause for the account holder to complete the challenge:
    # input("Complete OTP login in the browser, then press Enter here...")

    wait = WebDriverWait(driver, 30)
    wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "main h1")))

    # Optional diagnostic: ensure login ended at the intended destination.
    print("Current URL:", driver.current_url)

    if not driver.save_screenshot(str(OUTPUT)):
        raise OSError(f"Could not write screenshot to {OUTPUT.resolve()}")
    print("Saved:", OUTPUT.resolve())
finally:
    driver.quit()

The selector main h1 is only an example. Prefer a stable marker that appears after authentication, such as the account page heading or a known dashboard element. If the site opens the protected content in a new tab or window, switch to that window before waiting and capturing.

3. Choose the right readiness condition

driver.get() returning, or the document reporting readyState == "complete", does not guarantee that a JavaScript application has rendered the content you need. Wait for a meaningful state in the page:

  • Content is ready: wait for a relevant element to become visible.
  • A loading overlay is gone: wait for that overlay to become invisible.
  • A route transition is complete: wait for the destination URL and then a page-specific element.
# Wait for a known dashboard heading to appear.
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-testid='dashboard-title']")))

# Or wait for a loading indicator to disappear.
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, ".loading-overlay")))

Use explicit waits for the conditions that matter. Selenium warns that mixing implicit and explicit waits can produce unpredictable timeout behavior. A fixed sleep may be useful briefly while diagnosing a site, but it is usually less reliable: it can be too short on a slow response and waste time when the page is already ready. See Selenium’s waiting strategies documentation and browser options documentation.

4. Pick the capture scope and output

The normal WebDriver screenshot captures the current browser view. Use a WebElement screenshot when you only need one visible component. The standard current-window method should not be assumed to capture an entire long, scrollable document in every browser and environment; validate full-page capture separately if that is a requirement.

Need Python API Notes
Current browser view saved to disk driver.save_screenshot("page.png") Returns a boolean; check it when file-write failure matters.
Current view using file method driver.get_screenshot_as_file("page.png") Use a PNG filename; the API returns False for an I/O error.
PNG data for further processing driver.get_screenshot_as_png() Returns image bytes rather than writing a file.
Base64 image output driver.get_screenshot_as_base64() Useful when another component expects a base64 representation.
One element element.screenshot("panel.png") Locate the element after it is rendered; the element must be capturable in the browser.
# Capture one component after it becomes visible.
panel = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "section.account-summary")))
panel.screenshot("account-summary.png")

# Or keep the current view in memory as PNG bytes.
png_bytes = driver.get_screenshot_as_png()
Path("authenticated-page.png").write_bytes(png_bytes)

These methods are documented in the Selenium Python WebDriver API. Selenium also documents browser window and tab interactions in its windows and tabs guide.

5. Troubleshooting

Symptom Likely cause What to do
Screenshot shows the login page OTP was not completed, authentication did not succeed, or navigation redirected back to login. Inspect driver.current_url, complete the site’s normal challenge in this browser, and wait for a protected-page marker. Keep the same WebDriver session.
Wait times out after OTP The selector is wrong, the page is still loading, or the site displays a different post-login route. Inspect the current URL and page structure, then choose a stable element that actually appears on the destination page. Check whether a new window opened.
Screenshot is blank or missing late content The screenshot happened before client-side rendering, images, or the relevant component finished loading. Wait for the meaningful content or loading indicator state. For lazy-loaded sections, scroll them into view and wait for their content before capture.
Screenshot omits the bottom of a long page The ordinary driver screenshot is a viewport capture in the selected setup. Decide whether a viewport image is sufficient. If the entire document is required, choose and validate a full-page method for your browser and environment rather than assuming this API call provides it.
File is not created Path or permissions issue, or the target directory does not exist. Use an absolute writable path, create the directory first, and check the boolean result from save_screenshot or get_screenshot_as_file.
Unpredictable wait duration Implicit and explicit waits are combined. Use explicit waits for page-specific conditions and avoid mixing wait strategies.
Element screenshot fails The element is stale, not visible, or not yet present. Wait for the element again immediately before capture; reacquire it after navigation or a rerender.

6. Reliability, privacy, and cost

For repeatable captures, use stable selectors, explicit page-state waits, a deliberate viewport size, and a clear output path. Treat screenshots from authenticated pages as sensitive: they may show personal details, balances, identifiers, or account information. Store them only where intended and remove temporary files according to your own data-handling needs.

The Selenium workflow runs a browser and incurs the compute and maintenance costs of that environment; there is no per-screenshot Selenium API fee in the code shown, though browser infrastructure may have a cost. Reliability depends on the site’s authentication flow, OTP delivery, page changes, and the browser environment. Do not automate a login in ways the site disallows.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. Its one-call API is useful when you need a public page captured without running Selenium locally. Example for a public URL:

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

See the ScreenshotNeo API documentation for request options. ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed; its MCP server lets AI agents take screenshots; and 1,000 screenshots a month are free with no card, with paid plans starting at $5 for 3,000. ScreenshotNeo’s stated capture options include custom headers and cookies, but this public-page example is not a replacement for completing an interactive OTP challenge. For authorized authenticated captures, check the API documentation for the supported request configuration and your site’s rules.

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

FAQ

Does Selenium bypass an OTP?

No. This workflow assumes you complete the site’s normal OTP challenge as the authorized account holder.

Can I take the screenshot from the same browser after manual OTP entry?

Yes. Complete the challenge in the WebDriver-controlled browser and continue in that same session, then wait for the protected page marker.

Does the example capture the whole page?

It captures the current browser view. Full-page behavior depends on the chosen browser and capture method, so validate it separately when you need the entire document.