- Published on
How to Take Screenshots with Python
- Authors
- Name
- igor
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!