Todo desarrollador llega a un punto donde las tareas repetitivas empiezan a consumir más tiempo del que deberían. Descargar reportes, monitorear precios, revisar cambios en sitios web, responder consultas comunes… todas estas tareas se pueden — y se deberían — automatizar.
La buena noticia es que hoy, con Python y un poco de orientación, cualquier desarrollador puede construir su propio automation bot funcional en un par de horas. No necesitas un equipo de infraestructura ni una suscripción costosa a una plataforma SaaS. Solo necesitas código, una terminal y ganas de aprender.
En esta guía te voy a llevar desde cero hasta tener un bot funcional corriendo en tu máquina, capaz de scrapear información, procesarla con un modelo de lenguaje y reportar resultados. Sin magia. Sin dependencias innecesarias. Solo ingeniería práctica.
¿Qué vas a construir?
Vamos a crear un automation bot en Python que:
- Scrapea contenido de una o más fuentes web (simulando un feed de artículos o precios).
- Filtra y procesa la información usando lógica determinista primero, e inteligencia artificial después (sin API keys costosas).
- Genera un reporte formateado y lo envía a un canal de salida (archivo local, webhook, o consola).
- Corre en modo programado para ejecutarse cada cierto tiempo sin intervención humana.
No es ciencia ficción. Es código Python organizado en una arquitectura de agentes simple pero poderosa.
Fase 1: Setup del proyecto
Empecemos con la estructura básica. Vas a necesitar Python 3.10+ y las siguientes librerías:
mkdir mi-automation-bot && cd mi-automation-bot
python3 -m venv venv
source venv/bin/activate
pip install requests beautifulsoup4 schedule
Crea esta estructura de archivos:
mi-automation-bot/
├── bot.py # Orquestador principal
├── scraper.py # Módulo de extracción de datos
├── processor.py # Lógica de filtrado y procesamiento
├── reporter.py # Generación de reportes
└── config.py # Configuración centralizada
Separar responsabilidades desde el principio es lo que diferencia un script tirado de un sistema mantenible. Cada módulo tiene una función clara y se puede probar de forma independiente.
Fase 2: El scraper — obtener datos sin complicaciones
El scraper es el punto de entrada. Su trabajo es traer datos crudos desde una fuente. Vamos a construir uno que extraiga artículos desde un feed RSS o una página HTML:
# scraper.py
import requests
from bs4 import BeautifulSoup
from typing import List, Dict
class Scraper:
def __init__(self, sources: List[str]):
self.sources = sources
def fetch_articles(self) -> List[Dict]:
articles = []
for url in self.sources:
try:
resp = requests.get(url, timeout=15)
soup = BeautifulSoup(resp.text, 'html.parser')
# Estrategia: buscar <article> o <div class="post">
for item in soup.select('article, .post, .entry'):
title = item.find(['h1', 'h2', 'h3'])
link = item.find('a')
if title and link:
articles.append({
'title': title.get_text(strip=True),
'url': link.get('href'),
'source': url,
})
except Exception as e:
print(f"[WARN] Error en {url}: {e}")
return articles
Este scraper es genérico por diseño. Puedes apuntarlo a cualquier página que tenga artículos o entradas listadas. Si necesitas scrapear APIs JSON (como dev.to o Hashnode), solo agregas otro método en la misma clase. El principio es el mismo: entrada → parseo → lista de diccionarios.
Fase 3: El procesador — de datos crudos a información útil
Aquí es donde ocurre la magia. El procesador toma los artículos crudos y los filtra, clasifica y enriquece. En lugar de depender de una API externa para todo, usamos un enfoque híbrido:
Paso 1: Filtrado determinista (sin IA)
# processor.py
import re
from typing import List, Dict
class Processor:
def __init__(self, keywords: List[str]):
self.keywords = [k.lower() for k in keywords]
def filter_relevant(self, articles: List[Dict]) -> List[Dict]:
relevant = []
for art in articles:
title = art.get('title', '').lower()
# Score simple por coincidencia de keywords
score = sum(2 for kw in self.keywords if kw in title)
if score > 0:
art['relevance_score'] = score
relevant.append(art)
return sorted(relevant, key=lambda x: x['relevance_score'], reverse=True)
Este filtro por keywords es simple, rápido y no cuesta nada. Para la mayoría de los casos de uso, es suficiente. Filtra ruido, prioriza lo importante y te da una lista manejable para procesar.
Paso 2: Procesamiento con IA local (cuando lo necesitas)
Para tareas que requieren entendimiento semántico — resumir un artículo, extraer entidades, clasificar por intención — puedes integrar un modelo local pequeño:
def summarize_article(self, text: str) -> str:
"""Resume usando una heurística simple.
En producción, reemplazar con llamada a LLM local."""
sentences = text.split('. ')
if len(sentences) <= 3:
return text
# Toma las primeras 2 oraciones como resumen
return '. '.join(sentences[:2]) + '.'
Para equipos que quieren llevar esto al siguiente nivel, se puede conectar un LLM local (Ollama, llama.cpp) o una API. Pero el 80% del valor viene del filtrado determinista bien hecho.
Fase 4: El reporte — información accionable
Un bot que recolecta datos pero no los comunica de forma útil no sirve de nada. El reportero toma los datos procesados y los formatea:
# reporter.py
import json
from datetime import datetime
from typing import List, Dict
class Reporter:
def __init__(self, output_dir: str = "./reports"):
self.output_dir = output_dir
def generate_markdown(self, articles: List[Dict]) -> str:
lines = [
f"# Reporte Automático — {datetime.now().strftime('%Y-%m-%d %H:%M')}",
"",
f"**Total artículos relevantes:** {len(articles)}",
"",
]
for art in articles[:10]:
lines.append(f"- [{art['title']}]({art['url']}) — score: {art.get('relevance_score', 0)}")
return '\n'.join(lines)
def save(self, content: str):
path = f"{self.output_dir}/report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md"
with open(path, 'w') as f:
f.write(content)
print(f"[OK] Reporte guardado: {path}")
Fase 5: El orquestador — uniendo todo
El orquestador es el corazón del bot. Tiene dos responsabilidades: ejecutar el pipeline completo y programar ejecuciones periódicas.
# bot.py
import schedule
import time
from config import SOURCES, KEYWORDS, INTERVAL_MINUTES
from scraper import Scraper
from processor import Processor
from reporter import Reporter
def run_pipeline():
print(f"\n=== Pipeline iniciado: {time.ctime()} ===")
scraper = Scraper(SOURCES)
processor = Processor(KEYWORDS)
reporter = Reporter()
articles = scraper.fetch_articles()
print(f"Obtenidos {len(articles)} artículos crudos")
relevant = processor.filter_relevant(articles)
print(f"Filtrados {len(relevant)} artículos relevantes")
report = reporter.generate_markdown(relevant)
reporter.save(report)
print(f"=== Pipeline completado ===")
if __name__ == "__main__":
# Primera ejecución inmediata
run_pipeline()
# Luego cada N minutos
schedule.every(INTERVAL_MINUTES).minutes.do(run_pipeline)
while True:
schedule.run_pending()
time.sleep(30)
Y la configuración centralizada:
# config.py
SOURCES = [
"https://news.ycombinator.com",
"https://dev.to/feed",
"https://blog.dojofullstack.com/rss.xml",
]
KEYWORDS = ["python", "automation", "agent", "bot", "ai", "tutorial"]
INTERVAL_MINUTES = 60
Fase 6: Deploy — que corra solo
Tienes varias opciones para deployar tu bot:
| Opción | Cuándo usarla |
|---|---|
| Servidor personal (VPS) | Cuando necesitas control total y zero cost variable |
| GitHub Actions | Ideal para bots que corren en horarios fijos (cron: */60 * * * *) |
| AWS Lambda / Cloud Functions | Serverless, paga por ejecución. Bueno para bots ligeros |
| Raspberry Pi en casa | Barato, educativo, corre 24/7 |
Para un bot simple, GitHub Actions es la opción más práctica:
# .github/workflows/bot.yml
name: Automation Bot
on:
schedule:
- cron: '0 * * * *' # Cada hora
workflow_dispatch:
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install requests beautifulsoup4 schedule
- run: python bot.py
Con esto, tu bot corre cada hora sin que tengas que levantar un dedo. Los reportes se guardan como artefactos o puedes configurar un webhook para recibirlos en Telegram, Slack o Discord.
Más allá del bot básico
Una vez que tengas este pipeline funcionando, las posibilidades se multiplican:
- Agregar múltiples fuentes: RSS, APIs REST, WebSockets, bases de datos.
- Procesamiento en paralelo: Usa
concurrent.futurespara scrapear 10 fuentes a la vez en lugar de una por una. - Almacenamiento persistente: SQLite para llevar historial, deduplicar y generar tendencias.
- Notificaciones multicanal: Email, Telegram, Slack, Discord — todo desde el mismo reporter.
- Interfaz web: Un dashboard simple con Flask para ver reportes sin abrir la terminal.
La arquitectura de agentes no es complicada. Es ingeniería de software bien hecha: módulos pequeños, interfaces claras, y un orquestador que los une.
Lo que aprendiste hoy
Construiste un automation bot funcional desde cero. No usaste frameworks mágicos ni plataformas SaaS. Escribiste cada línea, entendiste cada decisión y tienes control total sobre el resultado.
Esto es lo que diferencia a un desarrollador que usa herramientas de uno que las construye.
En el bootcamp de DojoFullStack formamos desarrolladores que entienden los sistemas por dentro. No solo aprendes a usar Python: aprendes a diseñar arquitecturas modulares, a integrar inteligencia artificial de forma pragmática y a construir sistemas que funcionan solos mientras tú duermes.
“El mejor automation bot no es el más inteligente. Es el que nunca falla y siempre reporta.”
Sigue explorando estos temas en el blog de DojoFullStack y descubre cómo la automatización con Python y agentes de código está transformando la forma en que trabajamos como desarrolladores.