ScreenshotNeo

BlogHow-to

How to Print Navigator Attributes in Pyppeteer

Use Pyppeteer's page.evaluate() to read navigator properties in JavaScript and print the returned object in Python.

By the ScreenshotNeo team1 October 20265 min read

Direct answer: open a Pyppeteer page, call await page.evaluate() with a JavaScript function that returns the navigator properties you need, then print the returned Python dictionary.

navigator_info = await page.evaluate('''() => ({
    userAgent: navigator.userAgent,
    platform: navigator.platform,
    language: navigator.language,
    languages: navigator.languages,
})''')
print(navigator_info)

Page.evaluate() executes a JavaScript function or expression in the page context and returns its result to Python. See the Pyppeteer API reference and the Pyppeteer project README. The reference documents version 0.0.25, so check the documentation for the version installed in your project when compatibility matters.

Complete runnable example

Install Pyppeteer, launch Chromium, open a page, evaluate the attributes, and close the browser:

import asyncio
from pyppeteer import launch

async def main():
    browser = await launch(headless=True)
    page = await browser.newPage()
    await page.goto('https://example.com', {'waitUntil': 'networkidle2'})

    navigator_info = await page.evaluate('''() => ({
        userAgent: navigator.userAgent,
        platform: navigator.platform,
        language: navigator.language,
        languages: navigator.languages,
        cookieEnabled: navigator.cookieEnabled,
        onLine: navigator.onLine,
        hardwareConcurrency: navigator.hardwareConcurrency,
        deviceMemory: navigator.deviceMemory,
        maxTouchPoints: navigator.maxTouchPoints,
    })''')

    print(navigator_info)
    await browser.close()

asyncio.get_event_loop().run_until_complete(main())

Run it with python navigator_info.py. Some properties are browser-dependent and may be absent, None, or intentionally coarse. Treat the result as information about the current page context, not as a guaranteed description of the physical machine.

Read one navigator attribute

For a single property, pass an expression string:

platform = await page.evaluate('navigator.platform', force_expr=True)
print(platform)

force_expr=True tells Pyppeteer to interpret the string as an expression. This is useful when automatic detection could mistake an expression for a function body.

Collect custom and nested values safely

Return a plain serializable object. Avoid returning DOM nodes, class instances, or cyclic objects when the goal is to print data.

info = await page.evaluate('''() => {
    const n = navigator;
    return {
        identity: {
            userAgent: n.userAgent,
            appName: n.appName,
            appVersion: n.appVersion,
            product: n.product,
            platform: n.platform,
        },
        locale: {
            language: n.language,
            languages: Array.from(n.languages || []),
        },
        capabilities: {
            cookieEnabled: n.cookieEnabled,
            onLine: n.onLine,
            maxTouchPoints: n.maxTouchPoints,
        },
    };
}''')
print(info)

Use Array.from() for array-like browser values so the result crosses the JavaScript-to-Python boundary as a normal list.

Important Pyppeteer details

  • Evaluate in the right page: navigator values belong to the page and frame where the script runs. Call page.evaluate() after navigation and, for an iframe, evaluate through that frame.
  • Wait for navigation: call page.goto() with an appropriate waitUntil value before reading values that depend on the loaded document.
  • Use serializable returns: strings, numbers, booleans, arrays, and plain objects print cleanly in Python.
  • Prefer evaluate() for values: evaluateHandle() returns a JavaScript handle. It is useful for keeping a live browser-side object, but it is less convenient for printing an ordinary result.
  • Check availability: test optional properties in JavaScript before reading them. For example, deviceMemory: n.deviceMemory ?? null avoids an undefined value.

Useful navigator properties

Property Typical purpose Availability note
userAgent Inspect the browser user-agent string sent by the page context. Browser-controlled and can be reduced or changed.
platform Inspect the browser-reported platform value. Do not treat it as a secure OS identity.
language Read the preferred language. Usually a BCP 47 language tag.
languages Read the ordered language preferences. Convert it to a list before returning.
cookieEnabled Check whether cookies are enabled. Does not prove that a specific cookie will be accepted.
onLine Read the browser’s online status signal. It is a hint, not a connectivity test.
hardwareConcurrency Read the reported logical processor count. May be capped or generalized.
deviceMemory Read an approximate memory class where supported. Often unavailable outside Chromium-specific contexts.
maxTouchPoints Inspect the reported touch-point capability. Zero does not describe every input device in all environments.

Debugging checklist

  1. Confirm that page is an active Page object.
  2. Navigate before evaluating page-dependent values.
  3. Use force_expr=True for a bare expression such as navigator.platform.
  4. Return a plain object and convert array-like values with Array.from().
  5. Log the complete result and the installed Pyppeteer version when comparing environments.

Troubleshooting common errors

Error or symptom Cause Fix
SyntaxError or an expression treated as a function Pyppeteer guessed the wrong input type. Pass force_expr=True, or wrap the code in () => ....
NetworkError: Protocol error The page or browser closed while evaluation was running. Keep the browser open, await navigation, and avoid closing the page until the result is returned.
Property is missing or prints None The property is unsupported, restricted, or undefined in that browser context. Use a fallback such as n.deviceMemory ?? null and branch on the result.
Unexpected values across runs User-agent, locale, viewport, permissions, or browser version differs. Set those inputs explicitly and record the browser version with the navigator result.
Chromium fails to launch Pyppeteer cannot find or start its Chromium executable. Follow the installed version’s launch and Chromium download instructions, then retry with a minimal script.

Performance and reliability

A navigator read is normally a small in-page operation. The expensive parts are launching Chromium and loading the target page, so reuse one browser for multiple pages when appropriate and close pages when finished. Keep the evaluated object limited to fields needed for the diagnostic. For repeatable comparisons, pin the browser and Pyppeteer versions, set the same user agent and locale, and capture the URL and timestamp with the result.

Do not use navigator attributes as authentication, fraud-proof identity, or a security boundary. They are browser-exposed signals that can be overridden, generalized, or absent.

Or skip the browser setup

If you need a rendered screenshot while diagnosing how a page appears, ScreenshotNeo provides a GET endpoint that returns PNG, JPEG, WebP, or PDF. The API can set a user agent, headers, cookies, timezone, geolocation, viewport, device preset, custom JavaScript, and custom CSS, so you can reproduce the relevant browser conditions without maintaining Pyppeteer. See the ScreenshotNeo documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Before capture, ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server includes take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. One thousand screenshots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

FAQ

Can I print every navigator property?

You can request any property exposed by the browser, but unsupported or restricted properties may be undefined. Select the fields relevant to your debugging question.

Why does evaluateHandle() not print like evaluate()?

evaluateHandle() returns a browser-side JavaScript handle. Use evaluate() when you need the serializable value in Python.

Which Pyppeteer version does the reference describe?

The cited API reference is for version 0.0.25 and is historical. Verify behavior against the version installed in your project.