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
- Error Handling: Altijd try-except blokken gebruiken
- Logging: Log alle activiteiten voor debugging
- Configuration: Gebruik config files of environment variables
- Testing: Test scripts grondig voor ze automatisch draaien
- Monitoring: Houd bij of scripts correct draaien
- Security: Bewaar wachtwoorden nooit in scripts
- 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