Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To take a full-page screenshot with Python Selenium in mobile view, configure ChromeDriver’s mobile emulation, open the page, then call Chrome DevTools Protocol’s Page.captureScreenshot command with captureBeyondViewport: true. Decode its base64 result and write it to a PNG. Selenium’s ordinary screenshot methods capture the browser’s visible window, which is why a screenshot may stop at the bottom of the viewport. This guide shows the Chrome-specific full-page method, how to wait for dynamic content, and how to troubleshoot incomplete captures.
What you need and what this method does
This approach uses Selenium’s Python binding to control Chrome or Chromium through ChromeDriver, then uses Chrome DevTools Protocol (CDP) for the capture. The mobileEmulation Chrome option sets a mobile device profile or custom mobile metrics; CDP’s captureBeyondViewport extends the screenshot beyond the visible viewport. The capture data returned by CDP is base64-encoded and must be decoded before saving.
- Install Python and Selenium, and have a compatible Chrome or Chromium installation. Selenium Manager can generally manage the driver when you create
webdriver.Chrome(); if your environment manages ChromeDriver separately, its version must be compatible with the browser. - This implementation is Chrome-specific:
execute_cdp_cmdsends Chrome DevTools Protocol commands. It is not a browser-neutral Selenium screenshot recipe. - The dimensions and pixel ratio below are an example profile, not a claim that every phone uses those values. Choose and record the profile you need to reproduce.
ChromeDriver’s documentation describes both named-device emulation and custom device metrics: ChromeDriver mobile emulation. Selenium’s Python API documents execute_cdp_cmd and the regular screenshot methods: Selenium Chrome WebDriver API.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteRun a full-page capture in mobile view
The following script creates a Chrome session with a custom mobile viewport, navigates to a page, captures beyond that viewport, and writes the decoded PNG bytes to disk. Replace the target URL and metrics with the values appropriate for your test.
#1 Best Overall
import base64
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_experimental_option("mobileEmulation", {
"deviceMetrics": {
"width": 412,
"height": 823,
"pixelRatio": 2.0,
"mobile": True,
"touch": True,
}
})
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
# Replace this with waits for your page's real readiness conditions.
result = driver.execute_cdp_cmd("Page.captureScreenshot", {
"format": "png",
"fromSurface": True,
"captureBeyondViewport": True,
})
with open("full-page-mobile.png", "wb") as image_file:
image_file.write(base64.b64decode(result["data"]))
finally:
driver.quit()
- Select a mobile profile. Use a ChromeDriver-supported
deviceNameor set customdeviceMetrics. For repeatable results, keep a record of the selected device or the custom width, height, and pixel ratio. - Start the browser with emulation enabled. The emulation option must be set before creating the driver session.
- Navigate and wait for the page. A successful navigation does not guarantee that application data, web fonts, images, or below-the-fold lazy content have finished loading.
- Capture beyond the viewport. Set
captureBeyondViewporttotruein the CDP command. - Decode and save the result. The
datafield contains base64-encoded image data, not a ready-to-save PNG file. - Inspect the output. Check the bottom of the page, sticky elements, banners, and content that changes during capture.
Use a named device or custom metrics
ChromeDriver supports selecting a known profile with deviceName, or supplying custom metrics. For a named profile, replace the deviceMetrics value with the supported device name:
options.add_experimental_option("mobileEmulation", {
"deviceName": "Pixel 2"
})
Device names available to ChromeDriver can vary with the Chrome version, so use a name supported by the installed browser. Custom metrics are useful when you need a particular viewport rather than a built-in profile. ChromeDriver also documents custom user-agent and client-hint configuration; those can matter when a site’s server chooses content based on the browser identity, but they do not by themselves change the viewport dimensions.
Why the normal Selenium screenshot is not enough
Methods such as driver.save_screenshot("page.png") and driver.get_screenshot_as_file("page.png") capture the current browser window. In mobile emulation, that generally means the visible mobile viewport, not the entire document. CDP’s Page.captureScreenshot has a separate captureBeyondViewport option for content outside the viewport. The protocol also specifies that the returned image data is base64 encoded: CDP Page.captureScreenshot.
Rank #2
Wait for the page to be ready before capturing
There is no universal sleep duration that makes every page screenshot-ready. A fixed delay may waste time on a fast page and still miss content on a slow one. Prefer a condition tied to the page you are capturing, such as a page-specific element appearing or a known loading indicator disappearing.
Wait for an application element
For a site with a stable selector that appears after its main content loads, use Selenium’s explicit wait before issuing the CDP command:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "main"))
)
Replace main and the timeout with a meaningful selector and reasonable limit for the application. Presence only proves that the element exists; if the site renders it before populating it, wait for a more specific condition, such as visible text or a loading state ending.
Rank #3
Account for fonts, images, and lazy loading
Web pages often defer loading images until they approach the viewport. A full-page capture does not guarantee that every lazy image was requested first. If the page loads content during scrolling, scroll through it before capture, waiting for each relevant section or image to load. This can trigger lazy loading but may also cause scroll-triggered animations or infinite feeds to change the page. A page-specific preparation routine is more reliable than assuming that navigation completion means all content is present.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →For pages where fonts alter line wrapping, images shift layout, or content arrives asynchronously, wait for the page’s known readiness signals before capturing. Then review the saved image to confirm that the layout had settled. Avoid treating a single fixed sleep as a general solution.
Optional: inspect the page dimensions
When the resulting capture appears unexpectedly short or tall, inspect Chrome’s layout metrics before changing the screenshot code. CDP’s usage documentation demonstrates setting device metrics and capturing screenshots: Chrome DevTools Protocol. Metrics can help distinguish a short document from a capture that did not extend beyond the viewport. They do not make incomplete or dynamically changing page content load automatically.
Rank #4
Choose output and capture behavior deliberately
PNG, JPEG, or WebP
The example requests PNG, which is lossless and useful when you need crisp text or pixel-sensitive visual comparisons. CDP also defines JPEG and WebP formats; compressed formats can reduce file size but may change fine detail. Use a format supported by your downstream workflow and inspect the output when image fidelity matters.
Mobile fidelity is more than viewport size
Record the device profile or custom metrics alongside the screenshot. Width and height affect responsive breakpoints; pixel ratio affects the relationship between CSS pixels and image pixels; touch and mobile settings influence the emulated environment. If the site varies content based on user agent or client hints, configure those deliberately as well. A custom viewport should be described as that test profile rather than assumed to reproduce every behavior of a physical phone.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteDynamic and awkward page elements
- Sticky headers and fixed controls: They may appear at the top of the full-page image rather than repeating as they would across multiple scrolled screenshots. Inspect how the captured page represents overlays and fixed-position elements.
- Consent banners, popups, and chat widgets: They can cover content unless the site dismisses them or the test handles them. Screenshot capture does not automatically imply that these elements are removed.
- Cross-origin frames: Content inside a frame may have its own loading and access behavior. Confirm the frame is ready and visible in the resulting capture; do not assume that inspecting the top-level document guarantees frame completeness.
- Pages that change while scrolling: Infinite scrolling, live feeds, and scroll-triggered animations can produce a moving target. Define whether the goal is a snapshot at one moment, a finite loaded page, or a particular scroll state.
Troubleshoot incomplete or failed screenshots
| Symptom | Likely cause | What to try |
|---|---|---|
| Image ends at the mobile viewport | The regular WebDriver screenshot method was used, or captureBeyondViewport was omitted or false. |
Call Page.captureScreenshot through execute_cdp_cmd and set captureBeyondViewport to true. |
| CDP command is unavailable or rejected | The active browser driver is not ChromeDriver, or the command/parameters are unsupported by that browser version. | Confirm that the session is Chrome or Chromium controlled by ChromeDriver, check the exact CDP method and parameter names, and ensure browser and driver compatibility. |
KeyError: 'data' or invalid image bytes |
The response was not handled as expected, or the base64 result was not decoded correctly. | Inspect the returned object before writing; decode result["data"] using base64.b64decode and write bytes in binary mode ("wb"). |
| Images or sections are missing | Lazy loading or application requests had not completed at capture time. | Wait for page-specific readiness; scroll through lazy-loaded sections where appropriate, then verify that the content loaded before capture. |
| Unexpected responsive layout | The emulated viewport or device profile differs from the intended test, or site behavior depends on user agent/client hints. | Record and verify the selected profile and metrics. Configure documented user-agent or client-hint overrides only when needed for the test. |
| Browser starts but capture is blank or incomplete | The page may still be loading, failed to load, requires interaction, or changed while the capture was taken. | Check the page in the controlled browser, wait for its real ready state, handle required interaction, and retry after diagnosing the page rather than only increasing a blind delay. |
| Driver creation fails | Chrome/Chromium and ChromeDriver may be missing or incompatible, or the environment may not allow the browser to launch. | Install a supported browser, use a compatible driver-management setup, and review the driver startup error for environment-specific requirements. |
Browser support and an alternative workflow
The code above uses Chrome’s CDP interface, so it is appropriate when Chrome/Chromium behavior is the target. Firefox has separate full-document screenshot methods in Selenium’s Python binding; use the browser-specific API documented for the Firefox version and Selenium binding you run rather than sending Chrome CDP commands to Firefox. Selenium’s API reference distinguishes its driver-specific methods: Selenium Python API documentation.
Or skip the browser setup
If you need a screenshot rather than a Selenium-controlled browser session, ScreenshotNeo provides a website screenshot API and MCP server. A single GET request accepts a URL and returns an image or PDF. Its documented capture options include mobile device presets and custom viewports; see the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
ScreenshotNeo removes supported cookie/consent banners, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes screenshot tools for AI agents, and the free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month, with no card required.
Performance, repeatability, and cost considerations
A Selenium capture includes the overhead of starting and controlling a browser session. Reusing a driver for a batch of pages can avoid repeatedly starting Chrome, but each page still needs its own navigation, readiness checks, and capture. Full-page images can be large, especially at high device pixel ratios or on long documents, so consider available memory, image storage, and transfer size in a batch workflow.
For visual regression work, consistency matters more than choosing a vaguely phone-like viewport. Fix the browser environment, viewport metrics, device scale, target state, and timing conditions for comparisons. If the page contains volatile content such as dates, rotating banners, or personalized modules, account for it in the test rather than treating every pixel change as a layout regression. The official capture APIs define the mechanisms but do not specify a universal wait period or benchmark for every site.
Frequently Asked Questions
Can I use driver.save_screenshot() for the entire page?
It captures the current browser window. For Chrome full-page capture, use CDP’s Page.captureScreenshot with captureBeyondViewport enabled.
Does mobile emulation make the screenshot identical to a physical phone?
No. It configures an emulated browser profile and metrics; physical-device hardware and every device-specific behavior are not established by those settings.
Why is some content still missing when I enable captureBeyondViewport?
The option extends capture area; it does not force asynchronous requests, lazy images, or application content to finish loading. Wait for the page’s relevant readiness conditions before capture.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

