Automatização com Python: Guia Prático

Aprenda a automatizar tarefas com Python: manipulação de arquivos, web scraping básico, envio de emails e agendamento de scripts com exemplos reais.

7 min de leitura Equipe Python Brasil

Uma das maiores forças do Python é a capacidade de automatizar tarefas repetitivas. Se você passa tempo fazendo algo manual no computador, provavelmente dá para automatizar com Python. Neste guia prático, a gente vai explorar as formas mais comuns de automação com exemplos prontos para usar.

Manipulação de Arquivos e Pastas

Organizando arquivos por extensão

Um dos scripts mais úteis do dia a dia: organizar aquela pasta de downloads bagunçada.

import os
import shutil
from pathlib import Path

def organizar_pasta(pasta_origem):
    """Organiza arquivos de uma pasta por tipo/extensão."""

    categorias = {
        "Imagens": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".webp"],
        "Documentos": [".pdf", ".doc", ".docx", ".txt", ".xlsx", ".csv", ".pptx"],
        "Videos": [".mp4", ".avi", ".mkv", ".mov", ".wmv"],
        "Musicas": [".mp3", ".wav", ".flac", ".aac", ".ogg"],
        "Compactados": [".zip", ".rar", ".7z", ".tar", ".gz"],
        "Codigo": [".py", ".js", ".html", ".css", ".java", ".cpp"],
    }

    pasta = Path(pasta_origem)
    arquivos_movidos = 0

    for arquivo in pasta.iterdir():
        if arquivo.is_file():
            extensao = arquivo.suffix.lower()

            # Encontrar a categoria
            destino_nome = "Outros"
            for categoria, extensoes in categorias.items():
                if extensao in extensoes:
                    destino_nome = categoria
                    break

            # Criar pasta de destino se não existir
            destino = pasta / destino_nome
            destino.mkdir(exist_ok=True)

            # Mover o arquivo
            novo_caminho = destino / arquivo.name

            # Evitar sobrescrever
            if novo_caminho.exists():
                nome_sem_ext = arquivo.stem
                contador = 1
                while novo_caminho.exists():
                    novo_caminho = destino / f"{nome_sem_ext}_{contador}{extensao}"
                    contador += 1

            shutil.move(str(arquivo), str(novo_caminho))
            arquivos_movidos += 1
            print(f"  Movido: {arquivo.name} -> {destino_nome}/")

    print(f"\nTotal: {arquivos_movidos} arquivos organizados!")

# Uso
organizar_pasta("/home/usuario/Downloads")

Renomeando arquivos em lote

from pathlib import Path
import re

def renomear_fotos(pasta, prefixo="foto"):
    """Renomeia fotos em sequência: foto_001.jpg, foto_002.jpg, etc."""

    pasta = Path(pasta)
    extensoes_foto = {".jpg", ".jpeg", ".png", ".gif"}

    fotos = sorted([
        f for f in pasta.iterdir()
        if f.suffix.lower() in extensoes_foto
    ])

    for i, foto in enumerate(fotos, 1):
        novo_nome = f"{prefixo}_{i:03d}{foto.suffix.lower()}"
        novo_caminho = pasta / novo_nome

        foto.rename(novo_caminho)
        print(f"  {foto.name} -> {novo_nome}")

    print(f"\n{len(fotos)} fotos renomeadas!")

# Uso
renomear_fotos("/home/usuario/Fotos/Viagem", prefixo="viagem_sp")

Monitorando alterações em uma pasta

import time
from pathlib import Path
from datetime import datetime

def monitorar_pasta(pasta, intervalo=5):
    """Monitora uma pasta e avisa quando novos arquivos aparecem."""

    pasta = Path(pasta)
    arquivos_anteriores = set(pasta.iterdir())

    print(f"Monitorando: {pasta}")
    print(f"Verificando a cada {intervalo} segundos...")
    print("Pressione Ctrl+C para parar.\n")

    try:
        while True:
            arquivos_atuais = set(pasta.iterdir())

            novos = arquivos_atuais - arquivos_anteriores
            removidos = arquivos_anteriores - arquivos_atuais

            for arquivo in novos:
                hora = datetime.now().strftime("%H:%M:%S")
                tamanho = arquivo.stat().st_size / 1024
                print(f"[{hora}] NOVO: {arquivo.name} ({tamanho:.1f} KB)")

            for arquivo in removidos:
                hora = datetime.now().strftime("%H:%M:%S")
                print(f"[{hora}] REMOVIDO: {arquivo.name}")

            arquivos_anteriores = arquivos_atuais
            time.sleep(intervalo)

    except KeyboardInterrupt:
        print("\nMonitoramento encerrado.")

# Uso
monitorar_pasta("/home/usuario/Downloads")

Trabalhando com Planilhas

Lendo e processando Excel/CSV

import csv
from pathlib import Path

def processar_csv_vendas(arquivo_entrada, arquivo_saida):
    """Lê um CSV de vendas, calcula totais e gera relatório."""

    vendas_por_produto = {}
    total_geral = 0

    with open(arquivo_entrada, "r", encoding="utf-8") as f:
        leitor = csv.DictReader(f)

        for linha in leitor:
            produto = linha["produto"]
            quantidade = int(linha["quantidade"])
            preco = float(linha["preco"])
            total = quantidade * preco

            if produto not in vendas_por_produto:
                vendas_por_produto[produto] = {
                    "quantidade": 0,
                    "receita": 0,
                }

            vendas_por_produto[produto]["quantidade"] += quantidade
            vendas_por_produto[produto]["receita"] += total
            total_geral += total

    # Gerar relatório
    with open(arquivo_saida, "w", encoding="utf-8", newline="") as f:
        escritor = csv.writer(f)
        escritor.writerow(["Produto", "Qtd Vendida", "Receita Total"])

        for produto, dados in sorted(
            vendas_por_produto.items(),
            key=lambda x: x[1]["receita"],
            reverse=True
        ):
            escritor.writerow([
                produto,
                dados["quantidade"],
                f"R$ {dados['receita']:,.2f}"
            ])

        escritor.writerow([])
        escritor.writerow(["TOTAL GERAL", "", f"R$ {total_geral:,.2f}"])

    print(f"Relatório gerado: {arquivo_saida}")
    print(f"Total geral: R$ {total_geral:,.2f}")

# Uso
processar_csv_vendas("vendas.csv", "relatorio_vendas.csv")

Usando openpyxl para Excel

from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side

def criar_relatorio_excel(dados, arquivo_saida):
    """Cria um relatório Excel formatado."""

    wb = Workbook()
    ws = wb.active
    ws.title = "Relatório de Vendas"

    # Estilos
    titulo_font = Font(name="Arial", size=14, bold=True, color="FFFFFF")
    header_font = Font(name="Arial", size=11, bold=True, color="FFFFFF")
    header_fill = PatternFill(start_color="2F5496", fill_type="solid")
    titulo_fill = PatternFill(start_color="1F3864", fill_type="solid")

    # Título
    ws.merge_cells("A1:D1")
    ws["A1"] = "Relatório de Vendas - 2025"
    ws["A1"].font = titulo_font
    ws["A1"].fill = titulo_fill
    ws["A1"].alignment = Alignment(horizontal="center")

    # Cabeçalhos
    headers = ["Produto", "Quantidade", "Preço Unit.", "Total"]
    for col, header in enumerate(headers, 1):
        celula = ws.cell(row=3, column=col, value=header)
        celula.font = header_font
        celula.fill = header_fill
        celula.alignment = Alignment(horizontal="center")

    # Dados
    for i, item in enumerate(dados, 4):
        ws.cell(row=i, column=1, value=item["produto"])
        ws.cell(row=i, column=2, value=item["quantidade"])
        ws.cell(row=i, column=3, value=item["preco"])
        ws.cell(row=i, column=4, value=item["quantidade"] * item["preco"])

    # Ajustar largura das colunas
    ws.column_dimensions["A"].width = 20
    ws.column_dimensions["B"].width = 15
    ws.column_dimensions["C"].width = 15
    ws.column_dimensions["D"].width = 15

    wb.save(arquivo_saida)
    print(f"Relatório Excel criado: {arquivo_saida}")

# Uso
dados = [
    {"produto": "Notebook", "quantidade": 150, "preco": 3500},
    {"produto": "Mouse", "quantidade": 500, "preco": 89.90},
    {"produto": "Teclado", "quantidade": 300, "preco": 199.90},
    {"produto": "Monitor", "quantidade": 200, "preco": 1200},
]

criar_relatorio_excel(dados, "relatorio.xlsx")

Automação de Emails

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

def enviar_email(destinatario, assunto, corpo, anexo=None):
    """Envia email com suporte a HTML e anexos."""

    remetente = "seu_email@gmail.com"
    senha = "sua_senha_de_app"  # Use senha de aplicativo do Gmail

    msg = MIMEMultipart()
    msg["From"] = remetente
    msg["To"] = destinatario
    msg["Subject"] = assunto

    # Corpo do email em HTML
    html = f"""
    <html>
    <body>
        <h2 style="color: #2F5496;">Relatório Automático</h2>
        <p>{corpo}</p>
        <p style="color: #666;">
            Este email foi enviado automaticamente por Python.
        </p>
    </body>
    </html>
    """
    msg.attach(MIMEText(html, "html"))

    # Anexar arquivo se fornecido
    if anexo:
        with open(anexo, "rb") as f:
            parte = MIMEBase("application", "octet-stream")
            parte.set_payload(f.read())
            encoders.encode_base64(parte)
            parte.add_header(
                "Content-Disposition",
                f"attachment; filename={anexo.split('/')[-1]}"
            )
            msg.attach(parte)

    # Enviar
    try:
        with smtplib.SMTP("smtp.gmail.com", 587) as servidor:
            servidor.starttls()
            servidor.login(remetente, senha)
            servidor.send_message(msg)
        print(f"Email enviado para {destinatario}!")
    except Exception as e:
        print(f"Erro ao enviar email: {e}")

# Uso
enviar_email(
    "colega@empresa.com",
    "Relatório Semanal de Vendas",
    "Segue em anexo o relatório semanal de vendas.",
    anexo="relatorio.xlsx"
)

Envio em massa personalizado

import csv

def enviar_emails_em_massa(arquivo_csv):
    """Envia emails personalizados a partir de um CSV."""

    with open(arquivo_csv, "r", encoding="utf-8") as f:
        leitor = csv.DictReader(f)

        for linha in leitor:
            nome = linha["nome"]
            email = linha["email"]
            produto = linha["produto"]

            corpo = f"""
            Olá, {nome}!

            Gostaríamos de informar que o produto <strong>{produto}</strong>
            que você demonstrou interesse está com 20% de desconto esta semana.

            Aproveite essa oportunidade!
            """

            enviar_email(email, f"Oferta especial para você, {nome}!", corpo)
            print(f"  Enviado para {nome} ({email})")

# Uso
enviar_emails_em_massa("clientes.csv")

Agendamento de Tarefas

Usando a biblioteca schedule

import schedule
import time
from datetime import datetime

def backup_diario():
    """Realiza backup diário de arquivos importantes."""
    hora = datetime.now().strftime("%Y-%m-%d_%H-%M")
    print(f"[{hora}] Realizando backup...")
    # Aqui entraria a lógica do backup
    print("Backup concluído!")

def relatorio_vendas():
    """Gera relatório de vendas."""
    hora = datetime.now().strftime("%H:%M:%S")
    print(f"[{hora}] Gerando relatório de vendas...")
    # Aqui entraria a lógica do relatório

def verificar_sistema():
    """Verifica o estado do sistema."""
    hora = datetime.now().strftime("%H:%M:%S")
    print(f"[{hora}] Sistema OK")

# Agendando tarefas
schedule.every().day.at("08:00").do(backup_diario)
schedule.every().monday.at("09:00").do(relatorio_vendas)
schedule.every(30).minutes.do(verificar_sistema)

print("Agendador iniciado. Pressione Ctrl+C para parar.")
print("Tarefas agendadas:")
for job in schedule.get_jobs():
    print(f"  - {job}")

# Loop principal
while True:
    schedule.run_pending()
    time.sleep(1)

Web Scraping Básico

import requests
from bs4 import BeautifulSoup

def buscar_cotacao_dolar():
    """Busca a cotação atual do dólar."""

    url = "https://economia.awesomeapi.com.br/json/last/USD-BRL"

    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        dados = response.json()

        cotacao = dados["USDBRL"]
        print(f"Dólar (USD/BRL):")
        print(f"  Compra: R$ {float(cotacao['bid']):.4f}")
        print(f"  Venda:  R$ {float(cotacao['ask']):.4f}")
        print(f"  Máxima: R$ {float(cotacao['high']):.4f}")
        print(f"  Mínima: R$ {float(cotacao['low']):.4f}")
        print(f"  Atualizado em: {cotacao['create_date']}")

    except requests.RequestException as e:
        print(f"Erro ao buscar cotação: {e}")

buscar_cotacao_dolar()

Projeto Completo: Monitor de Preços

import requests
import json
from datetime import datetime
from pathlib import Path

class MonitorPrecos:
    """Monitora preços de produtos e avisa sobre quedas."""

    def __init__(self, arquivo_historico="precos_historico.json"):
        self.arquivo = arquivo_historico
        self.historico = self._carregar_historico()

    def _carregar_historico(self):
        if Path(self.arquivo).exists():
            with open(self.arquivo, "r") as f:
                return json.load(f)
        return {}

    def _salvar_historico(self):
        with open(self.arquivo, "w") as f:
            json.dump(self.historico, f, indent=2, default=str)

    def registrar_preco(self, produto, preco):
        agora = datetime.now().isoformat()

        if produto not in self.historico:
            self.historico[produto] = []

        self.historico[produto].append({
            "preco": preco,
            "data": agora,
        })

        self._salvar_historico()

        # Verificar se houve queda
        precos = self.historico[produto]
        if len(precos) >= 2:
            preco_anterior = precos[-2]["preco"]
            variacao = ((preco - preco_anterior) / preco_anterior) * 100

            if variacao < -5:
                print(f"ALERTA: {produto} caiu {abs(variacao):.1f}%!")
                print(f"  De R${preco_anterior:.2f} para R${preco:.2f}")

    def relatorio(self):
        print("\n" + "=" * 50)
        print("RELATÓRIO DE PREÇOS")
        print("=" * 50)

        for produto, registros in self.historico.items():
            precos = [r["preco"] for r in registros]
            print(f"\n{produto}:")
            print(f"  Atual:  R${precos[-1]:.2f}")
            print(f"  Mínimo: R${min(precos):.2f}")
            print(f"  Máximo: R${max(precos):.2f}")
            print(f"  Registros: {len(precos)}")

# Uso
monitor = MonitorPrecos()
monitor.registrar_preco("Notebook Dell", 4299.00)
monitor.registrar_preco("Mouse Logitech", 189.90)
monitor.registrar_preco("Notebook Dell", 3999.00)  # Queda!
monitor.relatorio()

Conclusão

A automação com Python é limitada apenas pela sua criatividade. Comece com tarefas simples que você faz manualmente todos os dias e vá evoluindo. Alguns próximos passos:

  1. Selenium: Para automação de navegadores web
  2. PyAutoGUI: Para automação de interface gráfica
  3. Watchdog: Para monitoramento avançado de arquivos
  4. Airflow: Para orquestração de pipelines de dados

A regra de ouro da automação: se você faz uma tarefa mais de três vezes, automatize. Seu eu do futuro vai agradecer!

E

Equipe Python Brasil

Contribuidor do Python Brasil — Aprenda Python em Português