Screenshot Indian News Websites in Malayalam with Node.js Playwright
Capture Malayalam news pages with Playwright in Node.js. Set up browsers, wait for fonts, choose a capture mode, and troubleshoot rendering issues.
Use Playwright in Node.js to open the news page, wait for its content and web fonts to become ready, then save a screenshot with page.screenshot(). Use fullPage: true for the entire scrollable page, a locator screenshot for one article or element, or the default screenshot for only the visible viewport. Check the resulting image for missing Malayalam glyphs or shaping issues; the right wait conditions depend on how the site loads its fonts and content.
This guide uses Manorama Online as an illustrative target. Its URL and page behavior can change, so verify the live page and select a stable page or element for your use case. Mathrubhumi is another example Malayalam news publisher. This article does not claim either site has been tested with Playwright. Manorama Online · Mathrubhumi.
1. Install Playwright and its browser
Start in a Node.js project. Playwright’s package and browser binaries are version-coupled: after installing or upgrading Playwright, install the browser binary for that version. Playwright installation guide · Browser installation guide.
npm init -y
npm install playwright
npx playwright install chromium
The example below uses Chromium explicitly. Playwright also supports Firefox and WebKit; choose the browser that matches your target or visual comparison environment. On Linux or CI systems, the browser installation guide explains installing OS dependencies as well.
2. Capture a Malayalam news page
Save this as screenshot.js and run node screenshot.js. It navigates to an illustrative target, waits for the load event, waits for the document’s font set to settle, and saves a full-page PNG.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
try {
const page = await browser.newPage({
viewport: { width: 1440, height: 1000 },
deviceScaleFactor: 1,
});
await page.goto('https://www.manoramaonline.com/', {
waitUntil: 'load',
timeout: 60_000,
});
// Wait for web fonts that the page has requested. This does not guarantee
// that every site has finished all asynchronous content updates.
await page.evaluate(() => document.fonts.ready);
await page.screenshot({
path: 'malayalam-news.png',
fullPage: true,
animations: 'disabled',
});
} finally {
await browser.close();
}
})();
Playwright’s screenshot API documents viewport, full-page, element, clipping, format, scale, masking, and stylesheet options. Page screenshot API.
3. Choose what to capture
| Goal | Approach | Trade-off |
|---|---|---|
| Visible page area | await page.screenshot({ path: 'viewport.png' }) |
Fast and bounded; content below the viewport is omitted. |
| Entire scrollable page | await page.screenshot({ path: 'full.png', fullPage: true }) |
Useful for a page record; very long pages can produce large images and may expose changing or lazy-loaded content. |
| One article or module | await page.locator('article').screenshot({ path: 'article.png' }) |
Focused output; the selector is site-specific and may need adjustment. |
| A measured rectangle | await page.screenshot({ path: 'region.png', clip: { x: 0, y: 0, width: 1200, height: 800 } }) |
Precise region; coordinates are relative to the page and must fit the capture area. |
For locator capture, first identify an element that exists on the live page. Do not assume a generic selector such as article matches a particular publisher’s layout:
const story = page.locator('article').first();
await story.waitFor({ state: 'visible', timeout: 15_000 });
await story.screenshot({ path: 'story.png' });
For a complete page screenshot, Playwright captures the full scrollable page rather than only the current viewport. Playwright’s fullPage option.
4. Malayalam fonts, glyphs, and shaping
Malayalam text depends on fonts that contain the required glyphs and on correct script shaping. A screenshot may show missing-glyph boxes, fallback fonts, or different-looking letter forms if the intended font has not loaded or the browser environment lacks a suitable fallback.
- Wait for navigation to reach the state appropriate to the page.
loadwaits for page resources, but a news site may continue updating content after that event. - Wait for the document’s font set with
await page.evaluate(() => document.fonts.ready)after navigation. - Inspect the saved PNG at its actual resolution. Look for missing glyphs, incorrect shaping, or a late font swap.
- If the page fetches fonts after an interaction or delayed script, wait for the relevant visible content or font request as well. No single generic readiness wait can guarantee every site’s font-loading strategy.
- For visual regression comparisons, keep the Playwright version, browser, operating system, and installed fonts stable. Playwright notes screenshots can differ between browsers and platforms because rendering and fonts vary. Visual comparisons and screenshot baselines.
Do not add a font override without checking the site’s rendering: a custom font may not include Malayalam glyphs or may change line wrapping and page height.
5. Readiness and dynamic news content
News pages can include ads, live modules, lazy-loaded images, and content that changes after initial navigation. Select the lightest wait that matches the capture goal, then add a condition for the content that matters.
// Wait for the navigation event, then a known page element.
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
await page.locator('main').waitFor({ state: 'visible', timeout: 15_000 });
// If the target's content needs a short settling window, make it explicit.
await page.waitForTimeout(1_000);
await page.screenshot({ path: 'capture.png', fullPage: true });
Replace main with a selector confirmed for the page being captured. A fixed delay can make a known asynchronous page settle, but it is not a proof that all content is ready. Avoid waiting indefinitely for network idle on sites with analytics, streaming, or long-lived requests; use a relevant element or a bounded delay when those requests never stop.
Full-page capture does not itself guarantee every lazy image was triggered or loaded. If lower-page images matter, scroll through the page before capture or wait for the specific images you need, then inspect the output. Keep the capture target stable when creating baselines; a stylesheet can hide known volatile elements during comparison. Playwright screenshot styles.
6. Output format, dimensions, and browser options
- PNG: lossless and the default screenshot format. Use it for visual inspection and comparisons.
- JPEG: smaller in many photo-heavy cases, but lossy. Pass
type: 'jpeg'and aqualityfrom 0 to 100. - WebP: use
type: 'webp'where supported by the installed Playwright/browser version. - Scale:
scale: 'css'yields CSS-pixel dimensions;scale: 'device'uses device scale and therefore more pixels on a high-DPI context. These are alternative modes. - Viewport: set
widthandheighton the page context to control responsive layout. Choose dimensions that match the screenshot’s intended use. - Browser: Chromium, Firefox, and WebKit are available. Cross-browser output can vary, so use the browser that represents the intended reader or keep it fixed for comparison.
await page.screenshot({
path: 'news.webp',
type: 'webp',
fullPage: true,
scale: 'css',
animations: 'disabled',
});
Use the screenshot API reference for the supported options and details for the installed version.
7. cURL, Python, and the ScreenshotNeo option
Playwright is the do-it-yourself browser method in this guide. If a hosted capture API suits the job, ScreenshotNeo accepts a URL and returns an image or PDF. Its parameter names used by other screenshot APIs also work. Find the available options in the ScreenshotNeo API documentation.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://www.manoramaonline.com/ -o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://www.manoramaonline.com/"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://www.manoramaonline.com/',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
ScreenshotNeo removes known cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing. Responses include X-Page-Verdict and X-Billed headers. It also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for AI agents. ScreenshotNeo is a website screenshot API and MCP server by Yorker Media; see ScreenshotNeo.
Or skip the browser setup
Use one API request to capture a page:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://www.manoramaonline.com/ -o shot.webp
Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Read the API documentation, then sign up for 1,000 free screenshots a month with no card.
8. Troubleshooting
| Symptom | Likely cause | What to try |
|---|---|---|
| Playwright says the executable is missing | The matching browser binary was not installed, or Playwright was upgraded. | Run npx playwright install chromium for the installed package version. |
| Browser launch fails on a Linux host | Required OS libraries may be missing. | Install the browser’s OS dependencies using the Playwright browser guide, then retry. |
| Navigation times out | The site is slow, keeps requests open, or did not reach the chosen event before the timeout. | Use a bounded timeout and a more appropriate event such as domcontentloaded; then wait for the specific content needed. |
| Malayalam appears as boxes or replacement characters | The intended font may not have loaded, or the environment may lack a font with those glyphs. | Wait for document.fonts.ready, inspect the actual PNG, and check the browser environment and page’s loaded fonts. |
| Letterforms or line breaks differ from another machine | Browser, operating system, or font versions differ. | Pin the browser and environment for comparisons and keep fonts consistent. |
| Lower-page images are missing | They may be lazy-loaded only after scrolling into view. | Scroll the page or wait for the required image elements to load before taking the full-page screenshot. |
| The screenshot contains changing ads or live content | The page continues changing after navigation. | Capture a defined region, wait for a relevant condition, or use a screenshot stylesheet to hide known volatile elements for comparisons. |
| The locator screenshot fails | The selector did not match an element, or the target is not visible. | Inspect the live DOM, use a page-specific selector, and wait for it to become visible. |
9. Performance, reliability, and cost
With Playwright, each capture requires a browser process and navigation to the target. Reuse a browser across multiple pages in a batch when appropriate, while isolating pages that need different contexts or settings. Close pages and browsers when finished. Full-page images, high device scale, and large viewports increase image dimensions and memory use; prefer a viewport or element capture when it meets the need.
For repeatable results, keep browser version, operating system, viewport, scale, and fonts fixed. News pages can change independently of your code, so visual differences may reflect new stories, ads, or layout changes. Use explicit timeouts and content readiness conditions, and record the chosen target URL and capture configuration alongside baselines.
Playwright is open-source software; running it has infrastructure costs such as compute, storage, and bandwidth, which depend on your workload and hosting. ScreenshotNeo pricing is Free for 1,000 shots per month with no card; Starter is $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. Only clean shots are billed under the product’s stated billing rules.
10. FAQ
How do I take a full-page screenshot of a Malayalam news website with Node.js Playwright?
Navigate with Playwright, wait for the relevant content and fonts, then call page.screenshot({ path: 'page.png', fullPage: true }).
Why are Malayalam letters missing in my screenshot?
The page font may not be ready, or the browser environment may lack a font with the needed glyphs. Wait for the document fonts and inspect the image and environment.
Can I capture only one article?
Yes. Find the article’s actual locator on the target page, wait until visible, and call that locator’s screenshot() method.
Does a full-page screenshot load every lazy image?
Not necessarily. Trigger lazy loading by scrolling or wait for the images you need, then check the saved capture.
Which browser should I use?
Use the browser relevant to your target workflow. Keep it fixed for visual comparisons, since browsers and platforms can render fonts differently.


