ScreenshotNeo

BlogHow-to

How to Take Mobile Viewport Screenshots with Selenium and Chrome

Configure ChromeDriver mobile emulation in Selenium, capture the visible viewport, and troubleshoot dimensions, waits, and device presets.

By the ScreenshotNeo team4 October 20267 min read

To take a mobile viewport screenshot with Selenium and Chrome, configure ChromeDriver’s mobile emulation before starting the browser session, open the page, wait for the state you need, and call WebDriver’s screenshot method. Use a named device preset or explicit viewport metrics. The example below uses a 390 × 844 CSS-pixel viewport with a device pixel ratio of 3.

This captures the currently visible viewport. It does not capture content below the fold. Chrome device emulation is a desktop Chrome approximation, not a substitute for checking behavior on a real phone.

1. Install Selenium and Chrome

Install Selenium in the Python environment where the script will run:

python -m pip install selenium

You also need Google Chrome. Selenium Manager, included with current Selenium releases, can generally discover or obtain a compatible driver when you create a Chrome session. In managed environments, install and configure Chrome and ChromeDriver according to your platform’s requirements.

2. Configure ChromeDriver mobile emulation

Set the mobile emulation capability on ChromeOptions before constructing the driver. Explicit metrics are useful when you need a reproducible width, height, and pixel ratio that does not depend on a device name being available in the installed Chrome version.

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

mobile_emulation = {
    "deviceMetrics": {
        "width": 390,
        "height": 844,
        "pixelRatio": 3.0,
    },
    "mobile": True,
    "touch": True,
}

options = webdriver.ChromeOptions()
options.add_experimental_option("mobileEmulation", mobile_emulation)

driver = webdriver.Chrome(options=options)
try:
    driver.get("https://example.com")
    WebDriverWait(driver, 20).until(
        lambda d: d.execute_script("return document.readyState") == "complete"
    )
    driver.save_screenshot("mobile-viewport.png")
finally:
    driver.quit()

Replace the example URL with the page you want to capture. The finally block closes Chrome even if navigation or screenshot capture fails.

Choose a named device preset

If ChromeDriver supports the device name in your installed version, you can use the preset instead of supplying metrics:

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_experimental_option(
    "mobileEmulation",
    {"deviceName": "Nexus 5"},
)

driver = webdriver.Chrome(options=options)
try:
    driver.get("https://example.com")
    driver.save_screenshot("mobile-viewport.png")
finally:
    driver.quit()

Preset availability and names can vary with Chrome and ChromeDriver versions. If a device name is rejected, choose a currently available name from the DevTools device list or switch to explicit metrics. ChromeDriver documents both forms and the mobile emulation capability in its mobile emulation guide.

3. Set the viewport and device behavior deliberately

Setting What it controls When to adjust it
deviceMetrics.width, height Emulated viewport dimensions in CSS pixels. Match the target layout or breakpoint. These are viewport dimensions, not necessarily the screenshot file’s pixel dimensions.
deviceMetrics.pixelRatio Device pixel ratio, which affects rendering density and output dimensions. Use the target device’s ratio when the rendered density matters. A ratio of 3 means a 390 CSS-pixel-wide viewport may render at roughly 1170 physical pixels wide.
mobile Enables mobile browser behavior in the emulation configuration. Keep it enabled for a mobile emulation. ChromeDriver documents it as defaulting to true in the documented mobile settings.
touch Enables touch-event emulation. Enable it when the page’s touch behavior is part of the state being captured. ChromeDriver documents it as defaulting to true in the documented mobile settings.
deviceName Selects a named DevTools emulated device profile. Use it for convenience when the name exists in the installed version; use explicit metrics for custom or stable dimensions.

ChromeDriver’s documented custom metrics include width, height, and pixel ratio. Mobile and touch behavior affect more than the screenshot’s dimensions. See the ChromeDriver documentation for the supported capability shape and details.

4. Wait for the page state you intend to capture

A screenshot records the rendered state at the moment it is taken. Navigation completing does not guarantee that client-side rendering, images, fonts, animations, or application data are ready. Choose a wait that matches the page:

  • Document loaded: wait for document.readyState to become complete, as in the main example.
  • Specific content present: wait for a stable element that signals the page is ready.
  • Known delay: use a fixed delay only when the page has a predictable delay and there is no useful readiness condition.

For example, wait for a page heading rather than sleeping an arbitrary number of seconds:

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

WebDriverWait(driver, 20).until(
    EC.visibility_of_element_located((By.CSS_SELECTOR, "main h1"))
)
driver.save_screenshot("mobile-viewport.png")

Choose a selector that reliably represents the content you need. If a page loads below-the-fold images lazily, a viewport capture may not trigger those images unless they are within or near the visible region.

5. Confirm whether you need a viewport or full-page image

driver.save_screenshot() captures the current browser viewport. It is appropriate for a screen-sized mobile image and does not, by itself, promise an image of the entire document. Chrome DevTools distinguishes the regular Capture screenshot action from Capture a full size screenshot. Use a full-page capture method when off-screen content is required, and verify that method’s behavior for your Chrome and Selenium setup. See the DevTools device mode documentation and Selenium’s official documentation.

6. Understand what mobile emulation does and does not prove

Chrome’s device mode runs desktop Chrome with emulated device characteristics. It is a first-order approximation: it cannot reproduce every real-device property, including mobile CPU architecture and all device-specific behavior. Treat the screenshot as evidence of the selected Chrome viewport and emulation settings. If a result depends on actual hardware, operating-system behavior, or a particular mobile browser, validate on that real device as well. See Chrome DevTools device mode and its guidance on remote debugging.

7. Troubleshoot common problems

Symptom Likely cause Fix
Chrome reports an unknown or invalid device name. The preset is not available in the ChromeDriver or Chrome version in use. Choose a listed current preset or replace deviceName with explicit deviceMetrics.
The layout does not match the target phone. The viewport dimensions, pixel ratio, mobile mode, or touch behavior do not match the intended emulation. Check width and height in CSS pixels, set the intended pixel ratio, and review the mobile and touch settings.
The file only shows the top part of the page. The screenshot captures the viewport, not the full document. Use a full-page capture approach if below-the-fold content is needed; do not interpret a viewport image as full-page.
The screenshot contains a loading state or missing content. The capture ran before the required application state, image, font, or data was ready. Wait for a page-specific element or other readiness condition. Increase the explicit wait timeout if the page can legitimately take longer.
Chrome fails to start or the session cannot be created. Chrome may be missing, or the browser and driver setup may be incompatible or unavailable in the environment. Install Chrome and use a compatible driver setup; check Selenium Manager access and environment restrictions, or configure the driver explicitly.
The captured result differs from a phone. Desktop Chrome emulation cannot reproduce all hardware, operating system, and mobile browser behavior. Use emulation for viewport and layout checks, then validate device-specific behavior on real hardware.

8. Performance, repeatability, and cost

For a single capture, browser startup and page loading usually make up most of the work; the screenshot call itself follows the current rendered state. Reuse a browser session when capturing several pages with the same configuration, but reset application state between captures when cookies, storage, or navigation could affect the result. Always close the driver when the batch finishes.

For repeatable comparisons, keep the Chrome version, emulation metrics, URL, page readiness condition, and relevant browser state consistent. A device preset can change across versions; explicit metrics avoid relying on a preset name but do not make desktop emulation equivalent to a physical device.

Running Selenium uses your own compute and browser environment; the cost depends on that infrastructure. This workflow has no ScreenshotNeo API charge because it uses a local WebDriver session. For hosted capture without managing Chrome, see the optional service below.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns an image or PDF. Its clean capture flow accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture.

For a mobile viewport, pass the desired viewport parameters along with the URL and API key. Check the ScreenshotNeo API documentation for parameter names and supported options.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -d width=390 \
  -d height=844 \
  -d device_scale_factor=3 \
  -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={
        "access_key": "YOUR_API_KEY",
        "url": "https://stripe.com",
        "width": 390,
        "height": 844,
        "device_scale_factor": 3,
    },
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com',
  width: '390',
  height: '844',
  device_scale_factor: '3',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

ScreenshotNeo offers 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000. Every feature is on every plan. Learn about ScreenshotNeo or sign up free for 1,000 screenshots a month, with no card.

FAQ

Does this run Chrome on a real phone?

No. ChromeDriver mobile emulation runs Chrome with simulated mobile settings on the host environment. Use a real device for behavior that depends on physical hardware or its operating system.

Why does the image have more pixels than the viewport width?

The viewport width is measured in CSS pixels. A device pixel ratio above 1 can produce a denser screenshot with more physical pixels.

Can I use a custom mobile width that is not a listed phone?

Yes. Use explicit device metrics for the width, height, and pixel ratio you want to emulate.

Will this capture browser chrome such as the address bar?

WebDriver page screenshots capture page content in the browser viewport, not the surrounding browser interface.