Cómo construir un agregador de bolsas de trabajo: fuentes, deduplicación y frescura
Un buen agregador de empleos se enfrenta a tres problemas de ingeniería: dónde obtener las ofertas, cómo deduplicarlas y cómo mantenerlas actualizadas. Soluciona esos problemas y el scraping será la parte fácil: aquí tienes el plan.
Un agregador de bolsas de trabajo es un motor de búsqueda para ofertas de empleo: extrae listados de muchas fuentes y los muestra en un solo lugar. Las partes difíciles no son las solicitudes HTTP, sino elegir las fuentes correctas, deduplicar el mismo empleo que aparece en cinco sitios y mantener todo fresco para no mostrar roles que se llenaron el mes pasado. Si aciertas en esos tres aspectos, tendrás un producto defendible; si fallas, tendrás un feed obsoleto y lleno de duplicados que erosiona la confianza. Esta guía es el plan de ingeniería: mezcla de fuentes, deduplicación canónica, frescura, el vertical de SERP de empleos y las líneas legales a respetar. Es informativa, no un consejo legal.
Fuente nivel 1: endpoints públicos de ATS
Los datos de empleo más limpios en internet no están en las bolsas de trabajo, sino en las páginas de carreras de las empresas impulsadas por sistemas de seguimiento de candidatos, la mayoría de los cuales exponen JSON estructurado. Greenhouse, Lever, Ashby, BambooHR, iCIMS, Paylocity y Workday ofrecen listados que puedes solicitar directamente, sin necesidad de analizar HTML. Un agregador de código abierto que extrae de los siete los obtiene en paralelo y ajusta el número de trabajadores a los límites de tasa de cada plataforma: aproximadamente 50 concurrentes para Workday, 30 para Greenhouse/Lever/iCIMS, 10 para BambooHR y 5 para los limitadores más estrictos. Este nivel te proporciona títulos canónicos, ubicaciones, bandas salariales y URLs de aplicación directamente del empleador, lo que lo convierte en la columna vertebral de cualquier agregador serio.
import httpx
# Greenhouse exposes a public board JSON endpoint per company slug
def fetch_greenhouse(slug: str) -> list[dict]:
url = f"https://boards-api.greenhouse.io/v1/boards/{slug}/jobs?content=true"
r = httpx.get(url, timeout=20)
r.raise_for_status()
jobs = r.json().get("jobs", [])
return [{
"source": "greenhouse",
"external_id": str(j["id"]),
"title": j["title"],
"company": slug,
"location": (j.get("location") or {}).get("name"),
"apply_url": j["absolute_url"],
"updated_at": j.get("updated_at"),
} for j in jobs]
rows = fetch_greenhouse("examplecompany")
print(len(rows), "roles")
Para encontrar empresas a las que consultar, recolecta slugs de ATS a gran escala desde un índice web en lugar de hacerlo manualmente: escanear los archivos de URL de Common Crawl en busca de patrones de dominios de ATS puede revelar decenas de miles de identificadores de empresas. Ese rastreo de descubrimiento es en sí mismo un trabajo de scraping; enrútalo a través de un proxy de centro de datos ya que el índice es indulgente y la velocidad importa más que la reputación de IP allí.
Fuente nivel 2: el vertical de SERP de empleos
Los feeds de ATS no incluyen todo lo publicado solo en sitios agregadores, bolsas regionales o la propia experiencia de empleos de Google. La forma eficiente de cubrir esa larga cola sin hacer scraping de una docena de bolsas individualmente es el vertical de SERP de empleos: una consulta estructurada que devuelve los empleos que Google muestra para un rol y ubicación, ya normalizados. Nuestra SERP API expone un vertical de empleos junto con noticias, imágenes y compras, para que puedas extraer listados de roles por palabra clave y ubicación como JSON e integrarlos en el mismo pipeline:
import httpx
def fetch_jobs_serp(query: str, location: str) -> list[dict]:
r = httpx.get(
"https://api.quantumproxies.io/serp",
params={"engine": "google_jobs", "q": query,
"location": location, "api_key": "QP_API_KEY"},
timeout=30,
)
jobs = r.json().get("jobs", [])
return [{
"source": "jobs_serp",
"external_id": j.get("job_id"),
"title": j.get("title"),
"company": j.get("company_name"),
"location": j.get("location"),
"apply_url": (j.get("apply_options") or [{}])[0].get("link"),
} for j in jobs]
serp_rows = fetch_jobs_serp("react developer", "Austin, TX")
Ejecuta la misma consulta en tus ciudades objetivo según un horario y tendrás cobertura geográfica que ningún feed de ATS individual proporciona. Debido a que los resultados de SERP cambian por ubicación, dirige cada consulta geográficamente: nuestro artículo sobre cómo funciona el scraping de SERP en 2026 cubre la mecánica de geolocalización y paginación.
Extrae el vertical de empleos de la SERP API

Deduplicación por clave canónica
El mismo empleo aparece rutinariamente en el sitio de la empresa, dos agregadores y una tarjeta de empleos de Google. Mostrarlo cuatro veces es la forma más rápida de parecer roto. La solución estándar es una clave canónica: normaliza y hashea la combinación de título del trabajo, empresa, ubicación y, cuando esté disponible, el ID de trabajo externo de la fuente. Convierte a minúsculas, elimina la puntuación y colapsa los espacios en blanco antes de hacer el hash para que "Sr. Software Engineer" y "senior software engineer" se colapsen juntos.
import re, hashlib
def canonical_key(job: dict) -> str:
def norm(s):
return re.sub(r"[^a-z0-9]+", " ", (s or "").lower()).strip()
basis = "|".join([
norm(job.get("title")),
norm(job.get("company")),
norm(job.get("location")),
(job.get("external_id") or ""),
])
return hashlib.sha1(basis.encode()).hexdigest()
def dedupe(rows: list[dict]) -> list[dict]:
seen, out = set(), []
for job in rows:
k = canonical_key(job)
if k not in seen:
seen.add(k)
out.append(job)
return out
La frescura es una característica, no una ocurrencia tardía
La credibilidad de una bolsa de trabajo es su frescura. Dos mecánicas la mantienen honesta: volver a obtener cada fuente según un horario (cada hora para feeds de ATS de alto volumen, diariamente para la larga cola) y eliminar cualquier cosa que no hayas vuelto a ver en una ventana móvil: 30 días es un valor predeterminado sensato, más corto para mercados de rápido movimiento. Rastrea un sello de tiempo de última vista por fuente y un conteo diario para que puedas detectar cuando una fuente se rompe silenciosamente; un agregador que observa su propio volumen puede abrir una alerta en el momento en que los números de una plataforma caen en picado. Nuestra nota sobre ejecutar scrapers como software de producción cubre la programación, detección de desviaciones y alertas.
Las líneas legales a respetar
Los datos de empleo son donde la ley de scraping se vuelve real, porque las publicaciones pueden contener datos personales (nombres de reclutadores, detalles de contacto) y descripciones detalladas son susceptibles de derechos de autor. La autoridad de protección de datos de Francia multó a la empresa KASPR con 240.000 € por extraer datos de contacto de LinkedIn sin el consentimiento adecuado; las sanciones del GDPR pueden alcanzar los 20 millones de euros o el 4% de la facturación global, y los daños por derechos de autor han llegado a 150.000 dólares por obra en casos de EE.UU. La postura más segura es estructural: prefiere feeds de ATS autorizados y el SERP de empleos en lugar de forzar el acceso a bolsas protegidas por inicio de sesión, almacena campos factuales (título, empresa, ubicación) en lugar de republicar descripciones completas con derechos de autor, y elimina los datos personales que no necesitas. Nuestro resumen sobre la legalidad del scraping web en 2026 y la saga de cumplimiento de LinkedIn profundizan más.

Dónde encajan los proxies
El nivel de ATS rara vez necesita IPs residenciales, pero el rastreo de descubrimiento, el vertical de SERP y cualquier scraping directo de bolsas sí lo hacen: Google y las bolsas más grandes limitan por IP y varían sus resultados geográficamente. Enruta esos a través de proxies residenciales rotativos con rotación por solicitud y geolocalización para que cada consulta de ciudad provenga de una ubicación coincidente. Mantén los niveles separados: centro de datos económico para el índice indulgente, residencial para los objetivos sensibles.
Preguntas frecuentes
¿Qué es un agregador de bolsas de trabajo?
Es un motor de búsqueda para ofertas de empleo que recopila listados de muchas fuentes: páginas de carreras de empresas, plataformas de ATS, otras bolsas y el SERP de empleos, los normaliza en un solo esquema, elimina duplicados y los presenta a los buscadores de empleo en un solo lugar buscable. El trabajo de ingeniería está en la obtención de fuentes, deduplicación y frescura, no solo en el scraping.
¿Cómo deduplicas las ofertas de trabajo de múltiples fuentes?
Construye una clave canónica normalizando y haciendo hash del título del trabajo, empresa, ubicación y el ID de trabajo externo de la fuente. Convierte a minúsculas, elimina la puntuación y colapsa los espacios en blanco primero para que las variantes ortográficas se colapsen juntas. Mantén la primera ocurrencia y elimina las coincidencias. Esto captura el mismo rol que aparece en el sitio del empleador, agregadores y empleos de Google.
¿Es legal hacer scraping de bolsas de trabajo?
Depende de la fuente, los datos y tu jurisdicción. Los campos de listados públicos son de menor riesgo que los datos personales o las descripciones completas con derechos de autor, y eludir muros de inicio de sesión aumenta la exposición al estilo CFAA. Los feeds de ATS autorizados y el SERP de empleos son las rutas más limpias. Las empresas han sido multadas severamente por extraer datos personales: busca asesoría legal para uso comercial.
¿Qué tan frescos deben estar los datos de empleo agregados?
Vuelve a obtener fuentes de alto volumen como los feeds de ATS cada hora y la larga cola diariamente, luego elimina cualquier listado que no hayas vuelto a ver dentro de una ventana móvil: 30 días es un valor predeterminado común. Rastrea un sello de tiempo de última vista por trabajo y monitorea el volumen por fuente para detectar una fuente rota antes de que los usuarios vean roles obsoletos.
Trata la agregación como tres problemas: fuentes, deduplicación, frescura, y el scraping se convierte en un detalle de apoyo. Lidera con feeds de ATS limpios y el vertical de SERP de empleos, deduplica con una clave canónica, poda agresivamente y mantén los rastreos sensibles en IPs residenciales rotativas. Esa es la diferencia entre un producto en el que la gente confía y un cementerio de enlaces muertos.