Published on

How to Take Screenshots with Python

Authors

Automatically capturing screenshots with Python is an incredible skill for developers, QA professionals, analysts, and even content creators. If you're thinking about taking screen captures for automated testing, monitoring websites, creating reports, or even generating web page previews, Python has fantastic tools to help you.

In this article, you'll discover how to do this using the most popular libraries, with practical examples and a step-by-step guide. Ready to automate screenshot capture with just a few lines of code? Let's go!

Why Use Python for Taking Screenshots?

One of Python's standout characteristics is how easy it is to read and write code. Additionally, it offers several excellent libraries for automating tasks, such as PyAutoGUI, Selenium, and Playwright. Choosing Python for taking screenshots brings the following benefits:

  • Simple to program and maintain
  • Works for screenshots on your own computer or remotely
  • Perfect for desktop applications, websites, and mobile apps
  • Runs on Linux, Windows, and macOS without problems
  • Easily connects with APIs, databases, and online services

Tools You Can Use

1. PyAutoGUI: Full Screen Capture

For capturing someone's computer screen, using PyAutoGUI presents itself as a quite agile and uncomplicated solution.

Installation:

pip install pyautogui

Example:

import pyautogui

screenshot = pyautogui.screenshot()
screenshot.save("screen.png")

This approach is perfect for automating screen actions or when you need to record everything that appears on the monitor, including desktop applications.

Advanced PyAutoGUI Usage:

import pyautogui
import time

# Take screenshot of a specific region
screenshot = pyautogui.screenshot(region=(0, 0, 800, 600))
screenshot.save("region_screenshot.png")

# Take screenshot after a delay
time.sleep(3)
screenshot = pyautogui.screenshot()
screenshot.save("delayed_screenshot.png")

# Get screen size
screen_width, screen_height = pyautogui.size()
print(f"Screen resolution: {screen_width}x{screen_height}")

2. Selenium: Capturing Websites and Web Pages

If you need to take screenshots of web pages, Selenium is one of the most beloved libraries in the Python world.

Installation:

pip install selenium

You'll also need to download ChromeDriver compatible with your Google Chrome version.

Basic Example:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com")
driver.save_screenshot("screenshot.png")
driver.quit()

Advanced Selenium Features:

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

def take_website_screenshot(url, filename):
    # Configure Chrome options
    chrome_options = Options()
    chrome_options.add_argument("--headless")  # Run in background
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("--window-size=1920,1080")
    
    driver = webdriver.Chrome(options=chrome_options)
    
    try:
        driver.get(url)
        
        # Wait for page to load
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.TAG_NAME, "body"))
        )
        
        # Take full page screenshot
        driver.execute_script("window.scrollTo(0, 0)")
        total_height = driver.execute_script("return document.body.scrollHeight")
        driver.set_window_size(1920, total_height)
        
        driver.save_screenshot(filename)
        print(f"Screenshot saved as {filename}")
        
    except Exception as e:
        print(f"Error taking screenshot: {e}")
    finally:
        driver.quit()

# Usage
take_website_screenshot("https://example.com", "website_screenshot.png")

Taking Screenshots of Specific Elements:

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

driver = webdriver.Chrome()
driver.get("https://example.com")

# Find specific element and take screenshot
element = driver.find_element(By.ID, "specific-element-id")
element.screenshot("element_screenshot.png")

driver.quit()

3. Playwright: High-Performance Website Capture

If you're looking for performance and modern features, Playwright is the perfect choice. It's similar to Puppeteer but offers support for multiple browsers.

Installation:

pip install playwright
playwright install

Basic Example:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("https://example.com")
    page.screenshot(path="screenshot.png", full_page=True)
    browser.close()

This method allows capturing the entire page, blocking ads, and even exporting to PDF.

Advanced Playwright Features:

from playwright.sync_api import sync_playwright
import time

def advanced_playwright_screenshot(url, filename):
    with sync_playwright() as p:
        # Launch browser with custom options
        browser = p.chromium.launch(
            headless=True,
            args=["--disable-blink-features=AutomationControlled"]
        )
        
        # Create new page with custom viewport
        page = browser.new_page(
            viewport={"width": 1920, "height": 1080}
        )
        
        # Block unnecessary resources for faster loading
        page.route("**/*.{png,jpg,jpeg,gif,svg,woff,woff2}", lambda route: route.abort())
        
        # Navigate and wait for page to load
        page.goto(url, wait_until="networkidle")
        
        # Wait for specific element
        page.wait_for_selector("body")
        
        # Take screenshot with options
        page.screenshot(
            path=filename,
            full_page=True,
            quality=90,
            type="png"
        )
        
        browser.close()
        print(f"Screenshot saved as {filename}")

# Usage
advanced_playwright_screenshot("https://example.com", "advanced_screenshot.png")

Taking Screenshots with Mobile Emulation:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    
    # Emulate iPhone 12
    iphone = p.devices["iPhone 12"]
    page = browser.new_page(**iphone)
    
    page.goto("https://example.com")
    page.screenshot(path="mobile_screenshot.png")
    
    browser.close()

4. Requests + HTML2Image: API-Based Screenshots

For a more lightweight approach, you can use requests to fetch HTML and convert it to images:

import requests
from html2image import Html2Image

def url_to_screenshot(url, filename):
    hti = Html2Image()
    
    # Take screenshot directly from URL
    hti.screenshot(url=url, save_as=filename)
    print(f"Screenshot saved as {filename}")

# Usage
url_to_screenshot("https://example.com", "api_screenshot.png")

Practical Applications

Let's explore some real-world use cases:

1. Automated Testing (QA):

Capture the visual state of a page to ensure frontend changes are correct.

def visual_regression_test(urls, baseline_dir, current_dir):
    for i, url in enumerate(urls):
        with sync_playwright() as p:
            browser = p.chromium.launch()
            page = browser.new_page()
            page.goto(url)
            
            # Take baseline screenshot
            baseline_path = f"{baseline_dir}/baseline_{i}.png"
            current_path = f"{current_dir}/current_{i}.png"
            
            page.screenshot(path=current_path, full_page=True)
            browser.close()
            
            # Compare with baseline (using external library like pixelmatch)
            print(f"Screenshot captured for {url}")

2. Visual Web Scraping:

Use alongside BeautifulSoup to collect and visualize web pages.

import requests
from bs4 import BeautifulSoup
from playwright.sync_api import sync_playwright

def scrape_with_screenshot(url):
    # Get page content
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')
    
    # Extract data
    title = soup.title.string if soup.title else "No title"
    
    # Take screenshot
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url)
        page.screenshot(path=f"screenshot_{title[:20]}.png")
        browser.close()
    
    return {"title": title, "screenshot": f"screenshot_{title[:20]}.png"}

3. Website Monitoring:

Schedule screenshots to track visual changes on specific pages.

import schedule
import time
from datetime import datetime

def monitor_website():
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"monitor_{timestamp}.png"
    
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto("https://example.com")
        page.screenshot(path=filename, full_page=True)
        browser.close()
    
    print(f"Monitoring screenshot saved: {filename}")

# Schedule monitoring every hour
schedule.every().hour.do(monitor_website)

while True:
    schedule.run_pending()
    time.sleep(60)

4. Bulk Screenshot Generation:

def bulk_screenshots(urls, output_dir="screenshots"):
    import os
    os.makedirs(output_dir, exist_ok=True)
    
    with sync_playwright() as p:
        browser = p.chromium.launch()
        
        for i, url in enumerate(urls):
            try:
                page = browser.new_page()
                page.goto(url, timeout=30000)
                
                # Clean filename from URL
                clean_name = url.replace("https://", "").replace("http://", "").replace("/", "_")
                filename = f"{output_dir}/{i+1}_{clean_name[:50]}.png"
                
                page.screenshot(path=filename, full_page=True)
                page.close()
                
                print(f"Screenshot {i+1}/{len(urls)} completed: {filename}")
                
            except Exception as e:
                print(f"Error with {url}: {e}")
        
        browser.close()

# Usage
urls = [
    "https://example.com",
    "https://github.com",
    "https://stackoverflow.com"
]
bulk_screenshots(urls)

Tips and Best Practices

1. Use full_page=True

Ensure you capture all website content:

page.screenshot(path="full_screenshot.png", full_page=True)

2. Combine with Pillow for Image Processing

Edit, resize, or crop your images:

from PIL import Image

# Open and resize screenshot
img = Image.open("screenshot.png")
img_resized = img.resize((800, 600))
img_resized.save("resized_screenshot.png")

# Crop specific area
cropped = img.crop((0, 0, 400, 300))
cropped.save("cropped_screenshot.png")

3. Schedule Automatic Captures

Use schedule, APScheduler, or cron:

import schedule
import time

def daily_screenshot():
    # Your screenshot code here
    pass

schedule.every().day.at("09:00").do(daily_screenshot)

while True:
    schedule.run_pending()
    time.sleep(60)

4. Error Handling and Retries

import time
from functools import wraps

def retry(max_attempts=3, delay=1):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_attempts - 1:
                        raise e
                    print(f"Attempt {attempt + 1} failed: {e}")
                    time.sleep(delay)
            return None
        return wrapper
    return decorator

@retry(max_attempts=3, delay=2)
def reliable_screenshot(url, filename):
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url)
        page.screenshot(path=filename, full_page=True)
        browser.close()

5. Memory and Performance Optimization

def optimized_bulk_screenshots(urls):
    with sync_playwright() as p:
        browser = p.chromium.launch()
        context = browser.new_context(
            viewport={"width": 1920, "height": 1080}
        )
        
        for url in urls:
            page = context.new_page()
            
            # Block unnecessary resources
            page.route("**/*.{png,jpg,jpeg,gif,svg}", lambda route: route.abort())
            
            page.goto(url, wait_until="networkidle")
            page.screenshot(path=f"screenshot_{hash(url)}.png")
            page.close()  # Important: close page to free memory
        
        browser.close()

Security and Privacy Considerations

Remember to:

  • Avoid capturing sensitive content without proper permission
  • Be mindful of LGPD/GDPR compliance
  • Respect robots.txt and website terms of service
  • Use rate limiting to avoid overwhelming servers
import time
import random

def respectful_screenshot(urls, min_delay=1, max_delay=3):
    for url in urls:
        # Random delay between requests
        delay = random.uniform(min_delay, max_delay)
        time.sleep(delay)
        
        # Your screenshot code here
        print(f"Taking screenshot of {url} after {delay:.2f}s delay")

Conclusion

In this article, you discovered how to take screenshots with Python using various tools for different purposes. Whether with PyAutoGUI, Selenium, Playwright, or through APIs, there's a solution for every need — from desktop automation to large-scale website capture.

Each tool has its strengths:

  • PyAutoGUI: Perfect for desktop application screenshots
  • Selenium: Great for web automation and testing
  • Playwright: Modern, fast, and feature-rich for web screenshots
  • API-based solutions: Lightweight and scalable

If you're interested in doing this in an easy, simple, and scalable way, consider using a screenshot API service for production applications!