Automation13 min readFebruary 26, 2026

10 Python Automation Scripts for Everyday Tasks

Save hours every week with these practical Python automation scripts. From file management to web scraping to email automation, these scripts handle the tedious work for you.

S

Soumyajit Sarkar

Partner & CTO, Greensolz

Why Automate with Python?

If you find yourself doing the same task more than twice, automate it. Python's rich standard library and third-party packages make it the best language for automation. From renaming hundreds of files to scraping websites to sending automated emails, Python can handle it all with surprisingly little code.

These ten scripts are practical, real-world solutions you can start using today. Each one is designed to solve a common problem and can be customized to fit your specific needs.

1. Bulk File Renamer

Rename hundreds of files in seconds using patterns. This script handles batch renaming with prefixes, suffixes, numbering, and date stamps.

import os
from datetime import datetime

def bulk_rename(directory, prefix="", suffix="", add_date=False, start_num=1):
    """Rename all files in a directory with a consistent pattern."""
    files = sorted(os.listdir(directory))
    files = [f for f in files if os.path.isfile(os.path.join(directory, f))]

    for i, filename in enumerate(files, start=start_num):
        name, ext = os.path.splitext(filename)
        new_name = f"{prefix}{name}{suffix}"

        if add_date:
            date_str = datetime.now().strftime("%Y%m%d")
            new_name = f"{new_name}_{date_str}"

        new_name = f"{new_name}_{i:03d}{ext}"
        old_path = os.path.join(directory, filename)
        new_path = os.path.join(directory, new_name)

        os.rename(old_path, new_path)
        print(f"Renamed: {filename} -> {new_name}")

# Usage
bulk_rename("./photos", prefix="vacation_", add_date=True)
      

2. Directory Organizer

Automatically sort files into folders based on their file type. Run this on your Downloads folder and watch the chaos become organized.

import os
import shutil

FILE_CATEGORIES = {
    "Images": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".webp"],
    "Documents": [".pdf", ".doc", ".docx", ".txt", ".xlsx", ".pptx", ".csv"],
    "Videos": [".mp4", ".avi", ".mkv", ".mov", ".wmv"],
    "Audio": [".mp3", ".wav", ".flac", ".aac", ".ogg"],
    "Archives": [".zip", ".rar", ".7z", ".tar", ".gz"],
    "Code": [".py", ".js", ".html", ".css", ".java", ".cpp", ".ts"],
}

def organize_directory(directory):
    """Sort files into categorized subdirectories."""
    for filename in os.listdir(directory):
        filepath = os.path.join(directory, filename)
        if os.path.isdir(filepath):
            continue

        ext = os.path.splitext(filename)[1].lower()
        category = "Other"

        for cat, extensions in FILE_CATEGORIES.items():
            if ext in extensions:
                category = cat
                break

        dest_dir = os.path.join(directory, category)
        os.makedirs(dest_dir, exist_ok=True)
        shutil.move(filepath, os.path.join(dest_dir, filename))
        print(f"Moved {filename} -> {category}/")

# Usage
organize_directory(os.path.expanduser("~/Downloads"))
      

3. Website Monitor

Check if websites are up and get notified when they go down. Useful for monitoring your own services or tracking competitor uptime.

import requests
import time
from datetime import datetime

def check_website(url, timeout=10):
    """Check if a website is responding and return status details."""
    try:
        response = requests.get(url, timeout=timeout)
        return {
            "url": url,
            "status": response.status_code,
            "response_time": response.elapsed.total_seconds(),
            "is_up": response.status_code == 200,
            "checked_at": datetime.now().isoformat()
        }
    except requests.RequestException as e:
        return {
            "url": url,
            "status": None,
            "response_time": None,
            "is_up": False,
            "error": str(e),
            "checked_at": datetime.now().isoformat()
        }

def monitor_sites(urls, interval=300):
    """Monitor multiple websites at regular intervals."""
    print(f"Monitoring {len(urls)} sites every {interval} seconds...")
    while True:
        for url in urls:
            result = check_website(url)
            status = "UP" if result["is_up"] else "DOWN"
            time_str = f'{result["response_time"]:.2f}s' if result["response_time"] else "N/A"
            print(f"[{result['checked_at']}] {status} | {url} | {time_str}")
        time.sleep(interval)

# Usage
sites = [
    "https://www.google.com",
    "https://www.github.com",
    "https://your-website.com"
]
monitor_sites(sites, interval=60)
      

4. CSV Data Processor

Clean, transform, and analyze CSV files automatically. This script handles common data cleaning tasks that would take ages in Excel.

import csv
from collections import Counter, defaultdict

def process_csv(input_file, output_file):
    """Clean and transform CSV data."""
    with open(input_file, "r") as f:
        reader = csv.DictReader(f)
        rows = list(reader)

    print(f"Loaded {len(rows)} rows")

    # Remove duplicates
    seen = set()
    unique_rows = []
    for row in rows:
        key = tuple(row.values())
        if key not in seen:
            seen.add(key)
            unique_rows.append(row)
    print(f"Removed {len(rows) - len(unique_rows)} duplicates")

    # Clean whitespace and standardize
    for row in unique_rows:
        for key in row:
            if isinstance(row[key], str):
                row[key] = row[key].strip()

    # Write cleaned data
    if unique_rows:
        with open(output_file, "w", newline="") as f:
            writer = csv.DictWriter(f, fieldnames=unique_rows[0].keys())
            writer.writeheader()
            writer.writerows(unique_rows)
        print(f"Saved {len(unique_rows)} clean rows to {output_file}")

    return unique_rows

# Usage
clean_data = process_csv("raw_data.csv", "clean_data.csv")
      

5. Automated Backup Script

Create timestamped backups of important directories. Never lose your work again.

import os
import shutil
from datetime import datetime

def create_backup(source_dirs, backup_root, max_backups=10):
    """Create compressed backups of specified directories."""
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    backup_dir = os.path.join(backup_root, f"backup_{timestamp}")
    os.makedirs(backup_dir, exist_ok=True)

    for source in source_dirs:
        if not os.path.exists(source):
            print(f"Warning: {source} does not exist, skipping")
            continue

        dir_name = os.path.basename(source)
        dest = os.path.join(backup_dir, dir_name)

        print(f"Backing up: {source}")
        shutil.copytree(source, dest, ignore=shutil.ignore_patterns(
            "*.pyc", "__pycache__", ".git", "node_modules", ".env"
        ))

    # Create compressed archive
    archive_name = os.path.join(backup_root, f"backup_{timestamp}")
    shutil.make_archive(archive_name, "zip", backup_dir)
    shutil.rmtree(backup_dir)  # Remove uncompressed copy
    print(f"Backup saved: {archive_name}.zip")

    # Clean old backups
    backups = sorted([
        f for f in os.listdir(backup_root) if f.startswith("backup_")
    ])
    while len(backups) > max_backups:
        old = os.path.join(backup_root, backups.pop(0))
        os.remove(old)
        print(f"Removed old backup: {old}")

# Usage
create_backup(
    source_dirs=["./projects", "./documents"],
    backup_root="./backups",
    max_backups=5
)
      

6. Password Generator

Generate secure, random passwords with customizable requirements.

import secrets
import string

def generate_password(length=16, uppercase=True, lowercase=True,
                      digits=True, special=True, exclude_chars=""):
    """Generate a cryptographically secure random password."""
    chars = ""
    required = []

    if uppercase:
        chars += string.ascii_uppercase
        required.append(secrets.choice(string.ascii_uppercase))
    if lowercase:
        chars += string.ascii_lowercase
        required.append(secrets.choice(string.ascii_lowercase))
    if digits:
        chars += string.digits
        required.append(secrets.choice(string.digits))
    if special:
        chars += string.punctuation
        required.append(secrets.choice(string.punctuation))

    chars = "".join(c for c in chars if c not in exclude_chars)
    remaining = length - len(required)
    password = required + [secrets.choice(chars) for _ in range(remaining)]
    secrets.SystemRandom().shuffle(password)
    return "".join(password)

# Generate multiple passwords
print("Generated Passwords:")
for i in range(5):
    pwd = generate_password(length=20, exclude_chars="0O1lI")
    strength = len(pwd) * 4  # Rough entropy estimate
    print(f"  {pwd}  (strength: {strength})")
      

7. Log File Analyzer

Parse and analyze log files to find errors, patterns, and anomalies.

import re
from collections import Counter
from datetime import datetime

def analyze_log(log_file):
    """Analyze a log file and generate a summary report."""
    errors = []
    warnings = []
    ip_addresses = []
    timestamps = []

    log_pattern = re.compile(
        r'(d{4}-d{2}-d{2} d{2}:d{2}:d{2}) [(w+)] (.+)'
    )
    ip_pattern = re.compile(r'd{1,3}.d{1,3}.d{1,3}.d{1,3}')

    with open(log_file, "r") as f:
        for line in f:
            match = log_pattern.match(line)
            if match:
                timestamp, level, message = match.groups()
                timestamps.append(timestamp)

                if level == "ERROR":
                    errors.append(message)
                elif level == "WARNING":
                    warnings.append(message)

            ips = ip_pattern.findall(line)
            ip_addresses.extend(ips)

    # Generate report
    report = {
        "total_lines": len(timestamps),
        "errors": len(errors),
        "warnings": len(warnings),
        "top_errors": Counter(errors).most_common(5),
        "top_ips": Counter(ip_addresses).most_common(10),
        "time_range": f"{timestamps[0]} to {timestamps[-1]}" if timestamps else "N/A"
    }

    print("=== Log Analysis Report ===")
    print(f"Total entries: {report['total_lines']}")
    print(f"Errors: {report['errors']}")
    print(f"Warnings: {report['warnings']}")
    print(f"Time range: {report['time_range']}")
    print(f"\nTop errors:")
    for error, count in report["top_errors"]:
        print(f"  [{count}x] {error[:80]}")

    return report

# Usage
# report = analyze_log("application.log")
      

8. Web Scraper

Extract data from websites automatically. Always respect robots.txt and terms of service.

import requests
from html.parser import HTMLParser

class SimpleHTMLParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.links = []
        self.headings = []
        self._current_tag = None

    def handle_starttag(self, tag, attrs):
        self._current_tag = tag
        if tag == "a":
            for attr, value in attrs:
                if attr == "href" and value:
                    self.links.append(value)

    def handle_data(self, data):
        if self._current_tag in ("h1", "h2", "h3"):
            self.headings.append(data.strip())

    def handle_endtag(self, tag):
        self._current_tag = None

def scrape_page(url):
    """Scrape a web page and extract links and headings."""
    headers = {"User-Agent": "Mozilla/5.0 (StudyPython Bot)"}
    response = requests.get(url, headers=headers, timeout=10)
    response.raise_for_status()

    parser = SimpleHTMLParser()
    parser.feed(response.text)

    return {
        "url": url,
        "status": response.status_code,
        "headings": parser.headings,
        "links": parser.links[:20],  # First 20 links
        "content_length": len(response.text)
    }

# Usage
# result = scrape_page("https://example.com")
# for heading in result["headings"]:
#     print(f"  {heading}")
      

9. System Resource Monitor

Monitor CPU, memory, and disk usage with alerts when resources run low.

import os
import platform
import subprocess

def get_system_info():
    """Gather system resource information."""
    info = {
        "platform": platform.system(),
        "platform_version": platform.version(),
        "architecture": platform.machine(),
        "processor": platform.processor(),
        "python_version": platform.python_version(),
    }
    return info

def get_directory_size(path):
    """Calculate the total size of a directory in bytes."""
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(path):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            if os.path.exists(fp):
                total_size += os.path.getsize(fp)
    return total_size

def format_bytes(bytes_val):
    """Convert bytes to human-readable format."""
    for unit in ["B", "KB", "MB", "GB", "TB"]:
        if bytes_val < 1024:
            return f"{bytes_val:.2f} {unit}"
        bytes_val /= 1024
    return f"{bytes_val:.2f} PB"

def system_report():
    """Generate a system resource report."""
    info = get_system_info()
    print("=== System Report ===")
    for key, value in info.items():
        print(f"  {key}: {value}")

    # Check important directory sizes
    home = os.path.expanduser("~")
    dirs_to_check = ["Documents", "Downloads", "Desktop"]
    print("\n=== Directory Sizes ===")
    for d in dirs_to_check:
        path = os.path.join(home, d)
        if os.path.exists(path):
            size = get_directory_size(path)
            print(f"  {d}: {format_bytes(size)}")

system_report()
      

10. Markdown to HTML Converter

Convert Markdown files to styled HTML documents, perfect for generating reports or documentation.

import re

def markdown_to_html(markdown_text):
    """Convert basic Markdown to HTML."""
    html = markdown_text

    # Headers
    html = re.sub(r'^### (.+)$', r'<h3>\1</h3>', html, flags=re.MULTILINE)
    html = re.sub(r'^## (.+)$', r'<h2>\1</h2>', html, flags=re.MULTILINE)
    html = re.sub(r'^# (.+)$', r'<h1>\1</h1>', html, flags=re.MULTILINE)

    # Bold and italic
    html = re.sub(r'**(.+?)**', r'<strong>\1</strong>', html)
    html = re.sub(r'*(.+?)*', r'<em>\1</em>', html)

    # Code blocks
    html = re.sub(r'\x60\x60\x60(.*?)\x60\x60\x60', r'<pre><code>\1</code></pre>', html, flags=re.DOTALL)
    html = re.sub(r'\x60(.+?)\x60', r'<code>\1</code>', html)

    # Links
    html = re.sub(r'[(.+?)]((.+?))', r'<a href="\2">\1</a>', html)

    # Unordered lists
    html = re.sub(r'^- (.+)$', r'<li>\1</li>', html, flags=re.MULTILINE)

    # Paragraphs
    lines = html.split("\n")
    result = []
    for line in lines:
        stripped = line.strip()
        if stripped and not stripped.startswith("<"):
            result.append(f"<p>{stripped}</p>")
        else:
            result.append(line)

    return "\n".join(result)

def convert_file(input_path, output_path):
    """Convert a Markdown file to an HTML file."""
    with open(input_path, "r") as f:
        md_content = f.read()

    html_content = markdown_to_html(md_content)

    full_html = f"""<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body {{ font-family: sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }}
        code {{ background: #f4f4f4; padding: 2px 6px; border-radius: 3px; }}
        pre {{ background: #f4f4f4; padding: 16px; border-radius: 8px; overflow-x: auto; }}
    </style>
</head>
<body>
{html_content}
</body>
</html>"""

    with open(output_path, "w") as f:
        f.write(full_html)
    print(f"Converted: {input_path} -> {output_path}")

# Usage
# convert_file("README.md", "readme.html")
      

Getting Started with Automation

The best way to learn automation is to identify a repetitive task in your daily life and write a script to handle it. Start small: maybe rename some files or organize your downloads folder. As you gain confidence, tackle larger projects like web scraping, data processing, or system monitoring.

Remember these best practices when writing automation scripts:

  • Always test on sample data first - Never run untested scripts on important files.
  • Add error handling - Use try/except blocks to handle unexpected situations gracefully.
  • Log your actions - Print or log what the script is doing so you can verify it worked correctly.
  • Make scripts configurable - Use command-line arguments or configuration files instead of hardcoding values.
  • Respect rate limits and terms of service - When scraping or making API calls, be a good citizen of the internet.

Python automation is one of the most practical skills you can develop. Once you start automating, you will find opportunities everywhere to save time and reduce errors.

pythonautomationscriptingproductivityweb scraping

Want to Master This Topic?

Our interactive course goes way beyond articles. Get hands-on with 31 lessons, 25 coding exercises, and AI-evaluated quizzes.