How to Take Selenium Screenshots of Hindi Government Websites with Headless Chrome
Capture Hindi government websites with Selenium and headless Chrome, then check that Devanagari fonts, page content, and layout rendered correctly.
Selenium can take a PNG screenshot of a Hindi government website in headless Chrome: start a Chrome WebDriver session, set a deliberate viewport, navigate to the page, wait for its content and fonts, then call save_screenshot(). A successful file write does not guarantee that Devanagari glyphs rendered correctly, so inspect the resulting image for missing characters, clipping, and layout changes.
This guide uses Python for the Selenium workflow and includes Chrome’s command-line alternative. It also covers font availability, timing, version matching, viewport behavior, common failures, and when to use a screenshot API instead.
1. Install and check the browser environment
Install Selenium in the Python environment that will run the capture:
python -m pip install selenium
You also need Chrome and a compatible ChromeDriver. Selenium’s Chrome guide says Selenium 4 is compatible with Chrome 75 and later, and Chrome and ChromeDriver major versions must match. Record both versions when debugging or reproducing captures. Selenium’s driver management can help obtain a driver, but the browser still needs to be installed and launchable in the environment.
In a minimal Linux container or CI image, check that the environment includes a font with Devanagari coverage. There is no single font package established as a universal fix for every Hindi website and operating system. The page may use its own web fonts, local fallback fonts, or a combination. Check the actual screenshot rather than assuming font installation succeeded.
Current Chrome Headless uses the same browser implementation as headful Chrome. Chrome’s Headless mode was updated in Chrome 112. Since Chrome 132, the old Headless implementation is available as a separate chrome-headless-shell binary; older instructions that rely on the old mode may not describe a current Chrome installation. See Chrome’s Headless mode documentation.
2. Capture a viewport screenshot with Selenium Python
This example saves the visible browser window to screenshot.png. Replace the example URL with the permitted page you need to capture. It waits for document load, then waits for the browser’s font set to finish loading when that API is available. Add a page-specific wait for sites that render important content after initial load.
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
url = "https://example.gov.in/"
output_path = Path("screenshot.png").resolve()
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--window-size=1365,1200")
# If Chrome is installed somewhere nonstandard, configure its binary explicitly:
# options.binary_location = "/path/to/chrome"
driver = webdriver.Chrome(options=options)
try:
driver.get(url)
WebDriverWait(driver, 30).until(
lambda browser: browser.execute_script(
"return document.readyState"
) == "complete"
)
# Wait for fonts known to the page to finish loading. This does not prove
# every glyph is correct; inspect the saved image as well.
driver.execute_async_script("""
const done = arguments[0];
if (document.fonts && document.fonts.ready) {
document.fonts.ready.then(() => done());
} else {
done();
}
""")
# Replace this with a meaningful landmark for the target site if needed.
# Example:
# WebDriverWait(driver, 20).until(
# lambda browser: browser.find_element("css selector", "main h1")
# )
saved = driver.save_screenshot(str(output_path))
if not saved:
raise RuntimeError(f"Screenshot could not be saved to {output_path}")
print(f"Saved screenshot to {output_path}")
finally:
driver.quit()
Install the Selenium package and browser dependencies in the same runtime that executes the script. On a machine where Chrome is available only under a custom path, set options.binary_location. The exact path and any container launch requirements depend on the operating system and image; verify them in that environment instead of copying universal flags from an unrelated setup.
Selenium documents save_screenshot() as saving the current window to PNG and returning false on an I/O failure. It captures the current viewport, not automatically the whole document. See the Python WebDriver API and Selenium’s Chrome documentation.
3. Check Hindi text and page readiness
Hindi rendering depends on the fonts available to the browser, the page’s font declarations, and when you take the screenshot. Inspect the output PNG at normal size and zoom in on text that uses Devanagari. Look for missing-glyph squares, detached or unexpected marks, fallback fonts that change line wrapping, clipped text, and headings or navigation that shifted because glyph metrics differ.
- Wait for the page’s important content:
document.readyState === "complete"is a useful baseline, but single-page applications, delayed APIs, and widgets can update afterward. Wait for a stable, page-specific landmark or state. - Wait for fonts:
document.fonts.readywaits for fonts known to the document to finish loading. It does not establish that a particular Devanagari font was selected or that every character has a glyph. - Check the environment: confirm the installed or bundled fonts have Devanagari coverage, especially in containers and minimal CI images. Compare the screenshot with headful Chrome on a known-good environment to isolate environment-specific rendering.
- Check layout at the chosen viewport: a different width can trigger mobile navigation, different line breaks, or hidden content. Match the dimensions to the result you need.
These are diagnostic checks, not a guarantee that one font installation or wait condition will fix every page. Official sources reviewed for this guide do not establish a required font package or a cross-platform Hindi rendering accuracy result.
4. Choose viewport and full-page behavior
--window-size=WIDTH,HEIGHT sets the browser window dimensions used for the capture. Choose them intentionally: the screenshot contains the visible window, and responsive websites may render different navigation and content at different widths. Selenium’s ordinary save_screenshot() captures that current window.
Do not assume that making the window very tall is a reliable way to capture the entire document. For a full-page result, use a browser-specific full-page capture method that you have verified with your Chrome version, or capture sections and stitch them, then inspect the result for gaps, repeated sticky headers, and lazy-loaded images. Chrome’s Headless documentation notes that full-page screenshots require additional work; the basic Selenium screenshot method is a viewport capture.
If you need a specific device scale factor or mobile emulation, configure and validate that separately. Keep viewport, scale, Chrome version, operating system, fonts, and URL fixed when you need reproducible output.
5. Chrome’s command-line screenshot option
For a one-off static page that does not need Selenium interactions or custom wait logic, Chrome can capture directly from the command line. Chrome’s reference documents --screenshot, --window-size, and --timeout:
google-chrome \
--headless \
--window-size=1365,1200 \
--timeout=10000 \
--screenshot=screenshot.png \
"https://example.gov.in/"
The executable name varies by installation and operating system. Check the Chrome binary path and command syntax available in your environment. The timeout controls when the command-line capture occurs; a fixed delay is not a substitute for checking a page-specific readiness condition when content or fonts load unpredictably. The basic CLI option is less expressive than WebDriver for interactions and condition-based waits. See Chrome’s Headless command-line reference.
6. Troubleshooting
| Symptom | Likely cause | What to check or change |
|---|---|---|
| ChromeDriver reports a session or version error | Chrome and ChromeDriver major versions do not match, or the browser is not available. | Check the installed browser and driver versions, confirm their major versions match, and verify the configured Chrome binary path. See Selenium’s Chrome guide. |
| The script runs but Hindi appears as squares or blank glyphs | The browser environment may lack a font with Devanagari coverage, or the intended web font did not load. | Inspect installed fonts and page font requests, wait for document.fonts.ready, and compare with headful Chrome in a known-good environment. Do not assume one package fixes all systems. |
| Text looks different or is clipped | A fallback font or a different viewport changed glyph metrics and line wrapping. | Check font loading and coverage, use the intended viewport width, and inspect the saved PNG at its actual dimensions. |
| Screenshot is blank or misses late content | The page may still be loading data or rendering client-side content when capture occurs. | Wait for a meaningful page landmark or application state. Use a longer timeout only if the page is expected to need it; a fixed delay can still be unreliable. |
| Screenshot contains only the top part of the page | save_screenshot() captures the current window. |
Use a verified full-page browser technique or capture and stitch sections. Check sticky elements and lazy images in the output. |
save_screenshot() returns false or the file is missing |
The output path may not be writable, or the process may be writing somewhere unexpected. | Use an absolute path, ensure its parent directory exists and is writable, and check the returned boolean. |
| Chrome fails to start in a container | The image may lack browser dependencies, have a different binary path, or impose environment-specific launch constraints. | Check the exact container image’s Chrome installation and logs. Container flags and packages are environment-specific; validate them for that image. |
7. Reliability, performance, and access considerations
For reliable repeated captures, record the target URL, capture timestamp, Chrome and ChromeDriver versions, operating-system or container image, installed fonts, viewport, and any relevant scale settings. Use a page-specific readiness condition, save to a known writable path, check the save result, and inspect a sample of output images. Treat capture success and visual correctness as separate checks.
Capture time depends on the target page, network, browser startup, and the waits your workflow uses; the sources do not establish a universal timing benchmark. Reusing a WebDriver session for a batch can avoid repeated startup overhead, but reset page-specific state between navigations and always quit the driver when finished. Keep timeouts bounded so a slow page does not hold a job indefinitely.
Before repeated or authenticated captures, check the site’s terms and any service-specific access constraints. The Indian Guidelines for Indian Government Websites and Apps portal provides GIGW manuals, validation resources, and accessibility guidance. Those resources do not determine whether a particular website permits automated access. Avoid sending credentials or personal data to capture systems that are not approved for them.
8. Or skip the browser setup
If you want a screenshot without installing or maintaining Chrome and ChromeDriver, ScreenshotNeo provides a website screenshot API and MCP server. One GET request accepts a URL and returns an image or PDF. The following cURL example saves a WebP capture:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.gov.in -o shot.webp
For the full request options and response details, see the ScreenshotNeo API documentation. Its clean-shot flow accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. The MCP server offers take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month, with no card required.
9. FAQ
Does a successful PNG save prove Hindi rendered correctly?
No. It confirms that a PNG was saved, not that Devanagari glyphs are present and laid out correctly. Inspect the image.
Can I use this with any Hindi government website?
The Selenium workflow can navigate to a reachable page, but site behavior, access rules, authentication, and rendering vary. Check the target site’s constraints and add waits for its actual content.
Should I use headless or headful Chrome to diagnose a font issue?
Compare both in the same environment, then compare headless output with a known-good environment. Current Chrome Headless shares the browser implementation with headful Chrome, but installed fonts and runtime conditions can still differ.
Can Selenium save a PDF instead of a screenshot?
The example uses Selenium’s PNG screenshot method. PDF generation is a separate browser workflow; choose and verify a PDF method for your browser and required paper settings.


