DEV Community

guzmanojero
guzmanojero

Posted on

Taking Screenshots in Selenium with Python

Python Selenium gives you multiple ways to capture the entire page, specific HTML elements, or even raw screenshot data.

Let's start!


1. Visible Viewport Screenshot

The simplest approach is capturing what’s currently visible in the browser window.

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.selenium.dev")

driver.save_screenshot("viewport.png")  # user-friendly alias
# or
driver.get_screenshot_as_file("viewport_file.png")  # same thing

driver.quit()

Enter fullscreen mode Exit fullscreen mode

It captures only the visible viewport, not the full scrollable page.

Take into consideration that save_screenshot() is just a wrapper around get_screenshot_as_file(). Both return True on success, False on I/O errors.


2. Full-Page Screenshot

Capturing the entire page depends on the browser.

Firefox (native support):

from selenium import webdriver

driver = webdriver.Firefox()
driver.get("https://www.selenium.dev")

driver.get_full_page_screenshot_as_file("fullpage.png")
Enter fullscreen mode Exit fullscreen mode

Chrome (using CDP):


import base64
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.selenium.dev")

# Ask Chrome for layout metrics (get full content size)
metrics = driver.execute_cdp_cmd("Page.getLayoutMetrics", {})
width = int(metrics["contentSize"]["width"])
height = int(metrics["contentSize"]["height"])

# Override device metrics so Chrome renders the ENTIRE page
# in a single "virtual" viewport (width x height).
driver.execute_cdp_cmd(
    "Emulation.setDeviceMetricsOverride",
    {
        "mobile": False,  # emulate desktop, not mobile
        "width": width,  # full content width
        "height": height,  # full content height
        "deviceScaleFactor": 1,  # 1 = normal DPI (increase for HiDPI/retina)
    },
)

# Capture screenshot of this expanded surface
fullpage_screenshot = driver.execute_cdp_cmd(
    "Page.captureScreenshot", {"fromSurface": True}
)

# Clear the override to restore normal browser behavior 
driver.execute_cdp_cmd("Emulation.clearDeviceMetricsOverride", {})

# Save full page image to file
with open("screenshoot_fullpage_chrome.png", "wb") as f:
    f.write(base64.b64decode(fullpage_screenshot["data"]))

driver.quit()
Enter fullscreen mode Exit fullscreen mode

As of the time of writing, Chrome does not natively support full-page screenshots, so the Chrome DevTools Protocol (CDP) method is necessary. This will change once the WebDriver BiDi protocol is completely implemented.

After setting a custom viewport with Emulation.setDeviceMetricsOverride, it’s a good practice to call Emulation.clearDeviceMetricsOverride once the screenshot is taken.

Technically, this step isn’t required if your script ends right after capturing the screenshot, since the browser session will close anyway. However, leaving the override active can affect later interactions: the page may render as if it were displayed on an abnormally large monitor, causing layout issues or unexpected JavaScript behavior.

Clearing the override restores Chrome to its normal viewport, ensuring consistent behavior if you plan to keep browsing, testing, or taking additional screenshots in the same session.


3. Screenshot of a Specific HTML Element

Sometimes you don’t need the whole page, just a particular element. Selenium makes this easy with WebElement.screenshot().

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.python.org/")

element = driver.find_element(By.ID, "documentation")

# element.screenshot
element.screenshot(f"screenshot_webelement.png")

driver.quit()
Enter fullscreen mode Exit fullscreen mode

Alternative: Get as PNG bytes

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.python.org/")

element = driver.find_element(By.ID, "documentation")

# Gets the screenshot of the current element as a binary data.
png_bytes = element.screenshot_as_png
with open("screenshot_webelement_bytes.png", "wb") as f:
    f.write(png_bytes)

driver.quit()
Enter fullscreen mode Exit fullscreen mode

Ok, we have reached the end of this article. I hope it helps 💪

Top comments (1)

Collapse
 
stark_zhuang_df5076f35c68 profile image
stark zhuang

Looks good to me, Thank you.