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!

Se você precisa de automações com alta concorrência ou ferramentas CLI de alta performance, vale conhecer também o ecossistema Go, que se destaca na criação de ferramentas de linha de comando e automação em larga escala.

E

Equipe Python Brasil

Contribuidor do Python Brasil — Aprenda Python em Português