Python Automatisering: Scripts Die Je Tijd Besparen

Ontdek hoe je repetitieve taken kunt automatiseren met Python scripts

De Kracht van Automatisering

Een van de mooiste aspecten van programmeren is de mogelijkheid om repetitieve taken te automatiseren. Python is bij uitstek geschikt voor automatisering dankzij zijn simpele syntax, uitgebreide standard library, en rijke ecosysteem van third-party packages.

In dit artikel verkennen we praktische automatiseringsscripts die je direct kunt gebruiken om tijd te besparen in je dagelijkse werk. Van file management tot email automatisering - Python kan het allemaal.

Waarom Python voor Automatisering?

  • Cross-platform: Werkt op Windows, Mac, en Linux
  • Rich standard library: Veel functionaliteit out-of-the-box
  • Third-party packages: Voor vrijwel elke taak is er een library
  • Eenvoudige syntax: Snel om te schrijven en te onderhouden
  • Scheduling: Gemakkelijk in te plannen met cron (Linux/Mac) of Task Scheduler (Windows)

1. File Management Automatisering

Een van de meest voorkomende automatiseringstaken is het organiseren van bestanden. Hier zijn enkele praktische voorbeelden:

Download Folder Organizer

import os
import shutil
from pathlib import Path
from datetime import datetime

def organize_downloads(download_path="~/Downloads"):
    """
    Organiseert downloads in mappen op basis van bestandstype
    """
    # Expand user path
    download_path = Path(download_path).expanduser()
    
    # File type mappings
    file_types = {
        'Afbeeldingen': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp'],
        'Documenten': ['.pdf', '.doc', '.docx', '.txt', '.rtf', '.odt'],
        'Spreadsheets': ['.xls', '.xlsx', '.csv', '.ods'],
        'Presentaties': ['.ppt', '.pptx', '.odp'],
        'Audio': ['.mp3', '.wav', '.flac', '.aac', '.ogg'],
        'Video': ['.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv'],
        'Archieven': ['.zip', '.rar', '.7z', '.tar', '.gz'],
        'Executables': ['.exe', '.msi', '.dmg', '.pkg', '.deb', '.rpm'],
        'Code': ['.py', '.js', '.html', '.css', '.php', '.java', '.cpp']
    }
    
    moved_files = []
    
    try:
        # Iterate through all files in download directory
        for file_path in download_path.iterdir():
            if file_path.is_file():
                file_extension = file_path.suffix.lower()
                
                # Find appropriate category
                target_folder = 'Overig'  # Default folder
                for category, extensions in file_types.items():
                    if file_extension in extensions:
                        target_folder = category
                        break
                
                # Create target directory if it doesn't exist
                target_dir = download_path / target_folder
                target_dir.mkdir(exist_ok=True)
                
                # Move file
                target_path = target_dir / file_path.name
                
                # Handle duplicate names
                counter = 1
                while target_path.exists():
                    name_parts = file_path.stem, counter, file_path.suffix
                    target_path = target_dir / f"{name_parts[0]}_{name_parts[1]}{name_parts[2]}"
                    counter += 1
                
                shutil.move(str(file_path), str(target_path))
                moved_files.append((file_path.name, target_folder))
                
    except Exception as e:
        print(f"Fout tijdens organiseren: {e}")
        return False
    
    # Report results
    if moved_files:
        print(f"โœ… {len(moved_files)} bestanden georganiseerd:")
        for filename, folder in moved_files:
            print(f"   ๐Ÿ“ {filename} โ†’ {folder}")
    else:
        print("โ„น๏ธ  Geen bestanden om te organiseren")
    
    return True

# Script uitvoeren
if __name__ == "__main__":
    organize_downloads()

Duplicate File Finder

import os
import hashlib
from pathlib import Path
from collections import defaultdict

def find_duplicates(directory, delete_duplicates=False):
    """
    Vindt duplicate bestanden op basis van MD5 hash
    """
    directory = Path(directory).expanduser()
    hash_map = defaultdict(list)
    
    print(f"๐Ÿ” Zoeken naar duplicaten in: {directory}")
    
    # Calculate hash for each file
    for file_path in directory.rglob('*'):
        if file_path.is_file():
            try:
                # Calculate MD5 hash
                hash_md5 = hashlib.md5()
                with open(file_path, "rb") as f:
                    for chunk in iter(lambda: f.read(4096), b""):
                        hash_md5.update(chunk)
                
                file_hash = hash_md5.hexdigest()
                hash_map[file_hash].append(file_path)
                
            except (PermissionError, OSError) as e:
                print(f"โš ๏ธ  Kan bestand niet lezen: {file_path} - {e}")
    
    # Find duplicates
    duplicates = {hash_val: paths for hash_val, paths in hash_map.items() if len(paths) > 1}
    
    if not duplicates:
        print("โœ… Geen duplicaten gevonden!")
        return
    
    total_duplicates = sum(len(paths) - 1 for paths in duplicates.values())
    total_size_saved = 0
    
    print(f"๐Ÿ” {len(duplicates)} groepen van duplicaten gevonden:")
    print("-" * 60)
    
    for hash_val, paths in duplicates.items():
        file_size = paths[0].stat().st_size
        size_mb = file_size / (1024 * 1024)
        
        print(f"\n๐Ÿ“„ Bestand grootte: {size_mb:.2f} MB")
        print(f"   Origineel: {paths[0]}")
        
        for duplicate in paths[1:]:
            print(f"   Duplicaat: {duplicate}")
            if delete_duplicates:
                try:
                    duplicate.unlink()
                    print(f"   โŒ Verwijderd: {duplicate}")
                    total_size_saved += file_size
                except OSError as e:
                    print(f"   โš ๏ธ  Kon niet verwijderen: {e}")
    
    if delete_duplicates and total_size_saved > 0:
        size_saved_mb = total_size_saved / (1024 * 1024)
        print(f"\n๐Ÿ’พ Totaal ruimte bespaard: {size_saved_mb:.2f} MB")
    else:
        potential_savings = sum(paths[0].stat().st_size * (len(paths) - 1) for paths in duplicates.values())
        potential_mb = potential_savings / (1024 * 1024)
        print(f"\n๐Ÿ’ก Potentiรซle ruimtebesparing: {potential_mb:.2f} MB")

# Usage
if __name__ == "__main__":
    # Alleen zoeken (veilig)
    find_duplicates("~/Documents")
    
    # Zoeken en verwijderen (voorzichtig!)
    # find_duplicates("~/Documents", delete_duplicates=True)

2. Email Automatisering

Email automatisering kan veel tijd besparen, vooral voor regelmatige communicatie:

Automated Email Reports

import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from datetime import datetime, timedelta
import os

class EmailAutomator:
    def __init__(self, smtp_server, smtp_port, email, password):
        self.smtp_server = smtp_server
        self.smtp_port = smtp_port
        self.email = email
        self.password = password
    
    def send_email(self, to_emails, subject, html_content, attachments=None):
        """
        Verstuur email met HTML content en optionele bijlagen
        """
        try:
            # Create message
            message = MIMEMultipart("alternative")
            message["Subject"] = subject
            message["From"] = self.email
            message["To"] = ", ".join(to_emails) if isinstance(to_emails, list) else to_emails
            
            # Add HTML content
            html_part = MIMEText(html_content, "html")
            message.attach(html_part)
            
            # Add attachments
            if attachments:
                for file_path in attachments:
                    if os.path.exists(file_path):
                        with open(file_path, "rb") as attachment:
                            part = MIMEBase('application', 'octet-stream')
                            part.set_payload(attachment.read())
                        
                        encoders.encode_base64(part)
                        part.add_header(
                            'Content-Disposition',
                            f'attachment; filename= {os.path.basename(file_path)}'
                        )
                        message.attach(part)
            
            # Create secure connection and send email
            context = ssl.create_default_context()
            with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
                server.starttls(context=context)
                server.login(self.email, self.password)
                text = message.as_string()
                server.sendmail(self.email, to_emails, text)
            
            print(f"โœ… Email verzonden naar: {to_emails}")
            return True
            
        except Exception as e:
            print(f"โŒ Fout bij verzenden email: {e}")
            return False

def generate_weekly_report():
    """
    Genereert een wekelijks rapport
    """
    today = datetime.now()
    week_start = today - timedelta(days=today.weekday())
    
    html_content = f"""
    
    
        

Wekelijks Rapport - Week van {week_start.strftime('%d-%m-%Y')}

๐Ÿ“Š Statistieken

  • Projecten voltooid: 5
  • Uren gewerkt: 40
  • Klanten gecontacteerd: 12

๐ŸŽฏ Doelen voor volgende week

  • 3 nieuwe projecten starten
  • Client presentatie voorbereiden
  • Team meeting organiseren

๐Ÿ“… Belangrijke data

Volgende week: Project deadline op donderdag

Dit rapport is automatisch gegenereerd op {today.strftime('%d-%m-%Y om %H:%M')}

""" return html_content # Usage example def send_weekly_reports(): # Email configuratie (gebruik environment variables voor security) email_sender = EmailAutomator( smtp_server="smtp.gmail.com", smtp_port=587, email=os.getenv("EMAIL_USER", "[email protected]"), password=os.getenv("EMAIL_PASSWORD", "your_app_password") ) # Rapport genereren report_content = generate_weekly_report() # Versturen naar team team_emails = ["[email protected]", "[email protected]"] email_sender.send_email( to_emails=team_emails, subject=f"Wekelijks Rapport - {datetime.now().strftime('%d-%m-%Y')}", html_content=report_content ) if __name__ == "__main__": send_weekly_reports()

3. Web Scraping Automatisering

Automatisch data verzamelen van websites kan veel tijd besparen:

import requests
from bs4 import BeautifulSoup
import csv
from datetime import datetime
import time
import json

class WebScraper:
    def __init__(self, delay=1):
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        })
        self.delay = delay
    
    def scrape_weather_data(self, city="Brussels"):
        """
        Scrape weer data (voorbeeld met openweathermap API)
        """
        try:
            api_key = os.getenv("OPENWEATHER_API_KEY", "your_api_key")
            url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric&lang=nl"
            
            response = self.session.get(url)
            response.raise_for_status()
            
            data = response.json()
            
            weather_info = {
                'city': data['name'],
                'temperature': data['main']['temp'],
                'feels_like': data['main']['feels_like'],
                'humidity': data['main']['humidity'],
                'description': data['weather'][0]['description'],
                'timestamp': datetime.now().isoformat()
            }
            
            return weather_info
            
        except Exception as e:
            print(f"Fout bij ophalen weerdata: {e}")
            return None
    
    def monitor_price_changes(self, product_urls):
        """
        Monitor prijsveranderingen van producten
        """
        price_data = []
        
        for url in product_urls:
            try:
                print(f"๐Ÿ” Controleren: {url}")
                
                response = self.session.get(url)
                soup = BeautifulSoup(response.content, 'html.parser')
                
                # Deze selectors moeten aangepast worden per website
                # Voorbeeld voor een generieke webshop:
                price_element = soup.select_one('.price, .price-current, [class*="price"]')
                title_element = soup.select_one('h1, .product-title, [class*="title"]')
                
                if price_element and title_element:
                    price_text = price_element.get_text(strip=True)
                    title = title_element.get_text(strip=True)
                    
                    # Extract price (basic example)
                    import re
                    price_match = re.search(r'[\d,]+\.?\d*', price_text.replace(',', '.'))
                    price = float(price_match.group()) if price_match else None
                    
                    price_data.append({
                        'url': url,
                        'title': title,
                        'price': price,
                        'timestamp': datetime.now().isoformat()
                    })
                
                time.sleep(self.delay)  # Respectful scraping
                
            except Exception as e:
                print(f"โŒ Fout bij {url}: {e}")
        
        return price_data
    
    def save_to_csv(self, data, filename):
        """
        Bewaar data naar CSV bestand
        """
        if not data:
            return
        
        with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
            writer = csv.DictWriter(csvfile, fieldnames=data[0].keys())
            writer.writeheader()
            writer.writerows(data)
        
        print(f"๐Ÿ’พ Data opgeslagen in {filename}")

# Usage
def daily_monitoring():
    scraper = WebScraper(delay=2)
    
    # Monitor weer
    weather = scraper.scrape_weather_data("Brussels")
    if weather:
        print(f"๐ŸŒค๏ธ  Weer in {weather['city']}: {weather['temperature']}ยฐC, {weather['description']}")
    
    # Monitor prijzen (voorbeelden - pas URLs aan)
    product_urls = [
        "https://example-shop.com/product1",
        "https://example-shop.com/product2"
    ]
    
    price_data = scraper.monitor_price_changes(product_urls)
    
    if price_data:
        filename = f"price_monitoring_{datetime.now().strftime('%Y%m%d')}.csv"
        scraper.save_to_csv(price_data, filename)

if __name__ == "__main__":
    daily_monitoring()

4. System Monitoring

Monitor je systeem en krijg alerts bij problemen:

import psutil
import smtplib
from email.mime.text import MIMEText
from datetime import datetime
import json
import os

class SystemMonitor:
    def __init__(self, email_config=None):
        self.email_config = email_config
        self.alerts_sent = set()  # Voorkom spam
    
    def check_disk_usage(self, threshold=90):
        """
        Controleer schijfgebruik
        """
        alerts = []
        
        for partition in psutil.disk_partitions():
            try:
                usage = psutil.disk_usage(partition.mountpoint)
                percent_used = (usage.used / usage.total) * 100
                
                if percent_used > threshold:
                    alert = {
                        'type': 'disk_usage',
                        'partition': partition.device,
                        'usage_percent': round(percent_used, 2),
                        'free_space_gb': round(usage.free / (1024**3), 2),
                        'timestamp': datetime.now().isoformat()
                    }
                    alerts.append(alert)
                    
            except PermissionError:
                continue
        
        return alerts
    
    def check_memory_usage(self, threshold=85):
        """
        Controleer geheugengebruik
        """
        memory = psutil.virtual_memory()
        
        if memory.percent > threshold:
            return {
                'type': 'memory_usage',
                'usage_percent': memory.percent,
                'available_gb': round(memory.available / (1024**3), 2),
                'timestamp': datetime.now().isoformat()
            }
        
        return None
    
    def check_cpu_usage(self, threshold=80, duration=5):
        """
        Controleer CPU gebruik
        """
        cpu_percent = psutil.cpu_percent(interval=duration)
        
        if cpu_percent > threshold:
            return {
                'type': 'cpu_usage',
                'usage_percent': cpu_percent,
                'timestamp': datetime.now().isoformat()
            }
        
        return None
    
    def check_running_processes(self, critical_processes):
        """
        Controleer of kritieke processen draaien
        """
        running_processes = [p.info['name'] for p in psutil.process_iter(['name'])]
        missing_processes = []
        
        for process in critical_processes:
            if process not in running_processes:
                missing_processes.append({
                    'type': 'missing_process',
                    'process_name': process,
                    'timestamp': datetime.now().isoformat()
                })
        
        return missing_processes
    
    def send_alert(self, alerts):
        """
        Verstuur alert via email
        """
        if not self.email_config or not alerts:
            return
        
        # Genereer alert bericht
        alert_text = "๐Ÿšจ SYSTEEM ALERT ๐Ÿšจ\n\n"
        
        for alert in alerts:
            if alert['type'] == 'disk_usage':
                alert_text += f"๐Ÿ’พ Schijf {alert['partition']}: {alert['usage_percent']}% gebruikt\n"
                alert_text += f"   Vrije ruimte: {alert['free_space_gb']} GB\n\n"
            
            elif alert['type'] == 'memory_usage':
                alert_text += f"๐Ÿง  Geheugen: {alert['usage_percent']}% gebruikt\n"
                alert_text += f"   Beschikbaar: {alert['available_gb']} GB\n\n"
            
            elif alert['type'] == 'cpu_usage':
                alert_text += f"โšก CPU: {alert['usage_percent']}% gebruikt\n\n"
            
            elif alert['type'] == 'missing_process':
                alert_text += f"๐Ÿ”ด Proces niet actief: {alert['process_name']}\n\n"
        
        alert_text += f"Tijd: {datetime.now().strftime('%d-%m-%Y %H:%M:%S')}"
        
        # Verstuur email (vereenvoudigde versie)
        try:
            msg = MIMEText(alert_text)
            msg['Subject'] = 'Systeem Alert'
            msg['From'] = self.email_config['from']
            msg['To'] = self.email_config['to']
            
            print(f"๐Ÿšจ Alert zou verzonden worden:\n{alert_text}")
            
        except Exception as e:
            print(f"Fout bij verzenden alert: {e}")
    
    def run_full_check(self):
        """
        Voer volledige systeemcheck uit
        """
        print(f"๐Ÿ” Systeemcheck gestart - {datetime.now().strftime('%H:%M:%S')}")
        
        all_alerts = []
        
        # Disk usage check
        disk_alerts = self.check_disk_usage(threshold=90)
        all_alerts.extend(disk_alerts)
        
        # Memory check
        memory_alert = self.check_memory_usage(threshold=85)
        if memory_alert:
            all_alerts.append(memory_alert)
        
        # CPU check
        cpu_alert = self.check_cpu_usage(threshold=80)
        if cpu_alert:
            all_alerts.append(cpu_alert)
        
        # Process check
        critical_processes = ['python', 'nginx', 'mysql']  # Pas aan naar je behoeften
        process_alerts = self.check_running_processes(critical_processes)
        all_alerts.extend(process_alerts)
        
        # Rapporteer resultaten
        if all_alerts:
            print(f"โš ๏ธ  {len(all_alerts)} alerts gevonden!")
            self.send_alert(all_alerts)
        else:
            print("โœ… Systeem draait normaal")
        
        # System info
        memory = psutil.virtual_memory()
        disk = psutil.disk_usage('/')
        
        print(f"๐Ÿ“Š Systeem Status:")
        print(f"   ๐Ÿ’พ Schijfgebruik: {(disk.used/disk.total)*100:.1f}%")
        print(f"   ๐Ÿง  Geheugen: {memory.percent:.1f}%")
        print(f"   โšก CPU: {psutil.cpu_percent(interval=1):.1f}%")
        
        return all_alerts

# Usage
def setup_monitoring():
    # Email configuratie (optioneel)
    email_config = {
        'from': '[email protected]',
        'to': '[email protected]'
    }
    
    monitor = SystemMonitor(email_config)
    
    # Eenmalige check
    monitor.run_full_check()

if __name__ == "__main__":
    setup_monitoring()

5. Scheduling en Deployment

Zorg ervoor dat je scripts automatisch draaien:

Windows Task Scheduler Setup

# create_task.py - Script om Windows Task te maken
import subprocess
import sys
from pathlib import Path

def create_windows_task(task_name, script_path, schedule_time="09:00"):
    """
    Maak een Windows Task Scheduler taak
    """
    # Zorg ervoor dat we het volledige pad hebben
    script_path = Path(script_path).absolute()
    python_path = sys.executable
    
    # Task XML configuratie
    task_xml = f"""

  
    
      2024-01-01T{schedule_time}:00
      
        1
      
    
  
  
    
      {python_path}
      {script_path}
    
  
"""
    
    # Schrijf XML naar tijdelijk bestand
    temp_xml = Path.cwd() / f"{task_name}.xml"
    with open(temp_xml, 'w', encoding='utf-16') as f:
        f.write(task_xml)
    
    try:
        # Maak de taak
        subprocess.run([
            'schtasks', '/create', 
            '/tn', task_name,
            '/xml', str(temp_xml)
        ], check=True)
        
        print(f"โœ… Task '{task_name}' succesvol aangemaakt")
        
    except subprocess.CalledProcessError as e:
        print(f"โŒ Fout bij aanmaken task: {e}")
    
    finally:
        # Ruim tijdelijk bestand op
        if temp_xml.exists():
            temp_xml.unlink()

# Usage
if __name__ == "__main__":
    create_windows_task(
        task_name="DailyFileOrganizer",
        script_path="C:/path/to/your/organize_downloads.py",
        schedule_time="10:00"
    )

Linux/Mac Cron Setup

#!/bin/bash
# setup_cron.sh - Script om cron jobs in te stellen

# Backup huidige crontab
crontab -l > cron_backup_$(date +%Y%m%d_%H%M%S).txt

# Voeg nieuwe cron jobs toe
(crontab -l 2>/dev/null; echo "# Python Automatisering Scripts") | crontab -
(crontab -l 2>/dev/null; echo "0 9 * * * /usr/bin/python3 /path/to/organize_downloads.py") | crontab -
(crontab -l 2>/dev/null; echo "0 10 * * 1 /usr/bin/python3 /path/to/weekly_report.py") | crontab -
(crontab -l 2>/dev/null; echo "*/30 * * * * /usr/bin/python3 /path/to/system_monitor.py") | crontab -

echo "โœ… Cron jobs ingesteld:"
echo "   - File organizer: dagelijks om 09:00"
echo "   - Weekly report: maandags om 10:00" 
echo "   - System monitor: elke 30 minuten"

crontab -l

Best Practices voor Automatisering

  1. Error Handling: Altijd try-except blokken gebruiken
  2. Logging: Log alle activiteiten voor debugging
  3. Configuration: Gebruik config files of environment variables
  4. Testing: Test scripts grondig voor ze automatisch draaien
  5. Monitoring: Houd bij of scripts correct draaien
  6. Security: Bewaar wachtwoorden nooit in scripts
  7. Backup: Maak backups voordat scripts data wijzigen

Logging Setup

import logging
from datetime import datetime
import os

def setup_logging(script_name):
    """
    Setup logging voor automatisering scripts
    """
    # Create logs directory
    log_dir = os.path.expanduser("~/automation_logs")
    os.makedirs(log_dir, exist_ok=True)
    
    # Log filename with date
    log_filename = f"{script_name}_{datetime.now().strftime('%Y%m%d')}.log"
    log_path = os.path.join(log_dir, log_filename)
    
    # Configure logging
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler(log_path),
            logging.StreamHandler()  # Ook naar console
        ]
    )
    
    return logging.getLogger(script_name)

# Usage in je scripts
logger = setup_logging("file_organizer")

def organize_files_with_logging():
    logger.info("๐Ÿš€ File organizer gestart")
    
    try:
        # Je automatisering code hier
        result = organize_downloads()
        
        if result:
            logger.info("โœ… File organisatie succesvol voltooid")
        else:
            logger.warning("โš ๏ธ  File organisatie gedeeltelijk mislukt")
            
    except Exception as e:
        logger.error(f"โŒ Kritieke fout: {e}")
        
    logger.info("๐Ÿ File organizer gestopt")

Veelgemaakte Fouten Vermijden

  • Hardcoded paths: Gebruik altijd Path() en expanduser()
  • Geen error handling: Scripts kunnen crashen zonder try-except
  • Te agressief schedulen: Geef systemen tijd om te herstellen
  • Geen rate limiting: Bij web scraping respectvol zijn
  • Credentials in code: Gebruik environment variables
  • Geen backups: Altijd backup maken voor destructieve operaties

Geavanceerde Automatisering

Voor complexere automatisering kun je kijken naar:

  • Apache Airflow: Workflow management
  • Celery: Distributed task queue
  • GitHub Actions: CI/CD automatisering
  • Docker: Consistent environments
  • Selenium: Browser automatisering

Conclusie

Python automatisering kan je enorm veel tijd besparen en je werk veel efficiรซnter maken. Begin klein met eenvoudige scripts en bouw langzaam meer complexe automatisering op. Vergeet niet om altijd te testen, te loggen, en veiligheidsmaatregelen te nemen.

De investering in tijd om automatisering op te zetten betaalt zich vaak al binnen enkele weken terug. En het mooiste is: eenmaal opgezet, blijven je scripts voor je werken, zelfs als je slaapt!

Klaar om je workflow te automatiseren?

Automatisering is een essentieel onderdeel van moderne Python development. In onze cursussen leer je niet alleen de basics, maar ook geavanceerde automatiseringstechnieken die je direct kunt toepassen in je werk.

Ontdek onze cursussen