How to capture screenshots of web pages with Selenium in an Indian language
Capture web pages with Selenium and troubleshoot missing or broken Indian-language text. Learn viewport, element, and full-page options.
Selenium captures the pixels rendered by the browser. In Python, use driver.save_screenshot("page.png") for the current viewport, or element.screenshot("element.png") for one element. A standard WebDriver screenshot is not automatically a full-page capture. If Hindi, Bengali, Tamil, Telugu, Gujarati, Kannada, Malayalam, Marathi, Punjabi, Odia, Urdu, or another script appears as boxes or malformed marks, check the page text, loaded web fonts, and fonts available to the browser environment before treating it as an image-encoding problem.
The workflow below uses Python, then covers browser configuration, full-page strategies, Indian-language rendering checks, troubleshooting, and alternate client examples. Selenium records the browser’s rendering; it does not add missing glyphs or repair page typography.
1. Capture a viewport or element with Python
Install Selenium in the environment that will run the script:
python -m pip install selenium
Recent Selenium versions can manage browser drivers through Selenium Manager. The browser itself still needs to be available in the runtime. This runnable example saves both the visible browser window and a target element:
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
out = Path("screenshots")
out.mkdir(parents=True, exist_ok=True)
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--window-size=1440,1000")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com/page")
# Replace this with a condition that proves your page content is ready.
WebDriverWait(driver, 20).until(
lambda d: d.find_element(By.CSS_SELECTOR, "main").is_displayed()
)
# PNG of the current visual viewport.
driver.save_screenshot(str(out / "viewport.png"))
# PNG bounded to the element's screenshot region.
main = driver.find_element(By.CSS_SELECTOR, "main")
main.screenshot(str(out / "main.png"))
finally:
driver.quit()
Replace the URL and selector with the page and element you need. The wait is deliberately site-specific: finding a main element is only a useful readiness signal if that element appears when the relevant content is ready. Selenium’s screenshot APIs and element screenshot behavior are documented by the Selenium project and the WebDriver specification.
Get screenshot bytes or Base64
When another part of your program handles storage or transport, save the returned bytes instead of writing directly through the driver:
png_bytes = driver.get_screenshot_as_png()
Path("screenshots/page.png").write_bytes(png_bytes)
png_base64 = driver.get_screenshot_as_base64()
These Chromium Python methods return the screenshot as PNG bytes or a Base64-encoded string. Use bytes for file or binary uploads; Base64 is useful when the receiving interface specifically expects encoded text. See the Selenium Chromium WebDriver API.
2. Choose the capture scope
| What you need | Method | What to expect |
|---|---|---|
| Visible browser window | driver.save_screenshot("page.png") |
PNG of the current visual viewport. |
| One component or element | element.screenshot("element.png") |
Image of the element’s visible bounding region after WebDriver scrolls it into view. |
| Entire long document | Browser/version-supported full-page capability or controlled scrolling and stitching | Requires an explicit full-page strategy; inspect the result for overlaps, missing content, and sticky elements. |
| Printable page | Chromium Python API driver.print_page() |
PDF output, not a PNG screenshot. |
The WebDriver standard defines a normal screenshot as the visual viewport image, and element screenshots use the element’s visible region. Chrome’s headless documentation also distinguishes its basic screenshot flow from a full-page workflow. See the WebDriver specification, Chrome headless documentation, and Selenium Python API.
Full-page capture
Do not assume increasing the window height gives a reliable full-document image: it may alter responsive layout, exceed browser limits, or still miss content that loads only as you scroll. Use a full-page feature supported by the browser and version in your environment, or scroll through the document and stitch viewport captures. For a scrolling approach:
- Set a fixed viewport and record the document height.
- Scroll in viewport-sized increments, allowing lazy content and fonts to load at each position.
- Capture each viewport and stitch the pieces with overlap handled deliberately.
- Check the final image for duplicated or missing bands, fixed headers repeated in every segment, animation changes, and content that appeared late.
A long page with lazy images, sticky headers, dynamic content, or very large dimensions needs visual validation. If exact document coverage matters, use a browser/version-supported full-page capture path and verify its output against the rendered page.
3. Configure headless mode and viewport size
Pass browser arguments through the options API for the binding you use. For Chrome in Python, the example above uses --headless and --window-size=1440,1000. Adjust dimensions to the target layout: fixed desktop dimensions help repeatability, while a smaller viewport exercises responsive behavior. Chrome documents headless screenshot usage and window sizing in its headless Chrome guide; its ChromeDriver capabilities documentation describes ChromeOptions configuration.
For reliable comparisons, record the browser and driver versions, operating system or container image, and viewport dimensions alongside the screenshot. Keep the browser and driver compatible with the runtime. Headless mode changes how the browser is launched; it does not change the fact that screenshots reflect rendered pixels.
4. Make Indian-language text render correctly
Selenium does not have a language-encoding switch for screenshot output. The browser lays out and paints the page, and the screenshot captures that result. Use this checklist when glyphs are missing, replaced by boxes, or have broken combining marks:
- Check the source text. Inspect the document encoding and the text in the DOM. Confirm the page response and document use the intended character encoding and that client-side code inserted the expected characters.
- Check computed styles. Inspect the element’s computed
font-familyand related styles. Confirm the intended web font was requested and loaded successfully. - Check the browser environment. In Linux, a container, or a headless runtime, verify that fonts covering the script are installed and visible to the browser process. Add suitable fonts to the runtime image when needed; there is no single font package that is right for every page and environment.
- Wait for the right conditions. Wait for the page-specific content marker and, where relevant, for web fonts. In page JavaScript,
document.fonts.readycan help indicate that font loading has settled; it does not prove the chosen font has the needed glyphs. - Inspect the saved image. Open the PNG produced in the same operating system, container, and browser version used by the automation. Correct DOM text alone does not prove the glyphs were painted correctly.
For example, after a site-specific content wait, a Python script can wait for the document’s font-loading promise to settle:
driver.execute_async_script("""
const done = arguments[arguments.length - 1];
document.fonts.ready.then(() => done());
""")
driver.save_screenshot("page.png")
This waits for the browser’s font set to finish loading; it does not install missing system fonts or guarantee script coverage. Diagnose the actual page and runtime when the output is still wrong.
5. Other Selenium language bindings
The title’s implementation language is Selenium with Python above. Selenium bindings expose screenshot methods in other languages too. Keep the browser setup and wait condition appropriate to your installed binding version. These examples show the core viewport capture pattern; add your own driver setup and page-specific readiness condition.
Java
import java.io.File;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.chrome.ChromeDriver;
ChromeDriver driver = new ChromeDriver();
try {
driver.get("https://example.com/page");
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
// Copy screenshot to your desired destination using your file API.
} finally {
driver.quit();
}
JavaScript (Node.js)
const { Builder, By } = require('selenium-webdriver');
const fs = require('node:fs/promises');
(async () => {
const driver = await new Builder().forBrowser('chrome').build();
try {
await driver.get('https://example.com/page');
await driver.wait(async () => {
const main = await driver.findElement(By.css('main'));
return main.isDisplayed();
}, 20000);
const png = await driver.takeScreenshot();
await fs.writeFile('page.png', Buffer.from(png, 'base64'));
} finally {
await driver.quit();
}
})();
The JavaScript example uses Selenium WebDriver’s Node package and Node’s built-in filesystem API. For language-specific setup and options, follow the Selenium documentation for the binding and browser you deploy.
6. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Indian-language characters appear as boxes | The selected or fallback font lacks the required glyphs, or a web font did not load. | Inspect computed font styles and font requests; provision a font with script coverage in the browser runtime where needed, then capture again. |
| Characters look separated or combining marks are misplaced | Font shaping or fallback differs in the actual browser environment, or the page’s intended font is unavailable. | Check the page’s rendered typography in the same browser and environment; confirm the intended font loaded and inspect the final PNG. |
| Text is missing although the DOM contains it | Capture ran before client rendering, font loading, or a delayed content request completed. | Wait for a meaningful page-specific element or state, then wait for relevant fonts before capturing. |
| Screenshot is blank or shows an old state | Navigation or asynchronous page work was not complete when capture ran. | Wait on a page-specific completion condition rather than relying only on navigation returning. |
| Only the top portion of a long page is present | A standard screenshot captures the visual viewport. | Use an explicit full-page capability for the browser/version or scroll and stitch, then inspect the full output. |
| Element screenshot is clipped | The element extends outside the visible region or its layout changes during capture. | Confirm the element is displayed, scroll it into view, and inspect its bounds and the resulting image. Remember the WebDriver element screenshot is limited to its visible region. |
| Driver fails to start | Browser availability, driver compatibility, or ChromeOptions differs in the runtime. | Install the browser in the execution environment, check browser/driver compatibility, and review the binding’s options configuration. |
| Output differs between local and CI | Different browser versions, fonts, viewport sizes, or runtime environments. | Align and record those inputs; inspect font availability and the captured PNG in CI’s environment. |
7. Performance, reliability, and output choices
- Wait only for what matters. A precise content or font readiness condition avoids capturing too early while avoiding arbitrary long sleeps. Choose the condition based on the page.
- Control the viewport. Fixed dimensions make captures easier to reproduce. They also determine responsive layout and the visible area.
- Account for full-page cost. Scrolling and stitching requires multiple captures and image processing; long pages may load more resources as they scroll. Validate lazy-loaded content and the stitched result.
- Keep the environment stable. Browser version, driver compatibility, fonts, operating system, and device dimensions all affect rendered output.
- Choose the artifact deliberately. Use PNG for screenshot output; use the documented Chromium
print_page()path when the desired deliverable is PDF. They are different outputs. - Inspect failures instead of retrying blindly. A retry will not fix absent fonts or a selector that never becomes ready. Capture diagnostic details such as the browser version, viewport, page URL, readiness condition, and a representative output.
Selenium itself is open-source browser automation software; this workflow’s direct resource use comes from running the browser, loading the page, and optionally processing full-page images. The dossier does not establish a universal runtime cost or speed benchmark, so size the environment against your own pages and capture frequency.
8. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. One GET request returns an image or PDF; its parameters also work with names used by other screenshot APIs, which can make switching easier. See the ScreenshotNeo API documentation for options and setup.
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}`);
Cookie banners, popups, and chat widgets are removed before the shot, and each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed; response headers report the page verdict and billing status. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Every feature is on every plan.
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
9. FAQ
Does Selenium translate or encode the page into an Indian language?
No. It captures the browser-rendered page. The page content and browser fonts determine which script glyphs appear.
Can I save a Selenium screenshot as JPEG?
The documented Selenium screenshot methods described here return or save PNG. If you need another image format, convert the captured PNG with an image-processing library after capture.
Is an element screenshot the same as a full-page screenshot?
No. It covers an element’s visible bounding region. A full document requires a separate full-page strategy.
Can I get a PDF from Selenium?
The Selenium Python Chromium API documents print_page() for PDF output. It produces a print-oriented PDF, not a PNG screenshot.


