Escanea portales de empleo
Configura y ejecuta el escáner de portales para encontrar nuevas ofertas de empleo automáticamente.
Esta guía explica cómo configurar portals.yml y ejecutar el escáner de portales para encontrar nuevas ofertas de empleo automáticamente.
Antes de empezar
Asegúrate de haber completado la guía de Inicio rápido. Necesitas tener cv.md y modes/_profile.md en su sitio para que el escaneo sea útil.
Configura portals.yml
portals.yml es el archivo que controla qué busca el escáner y dónde lo busca. Lo creas una vez a partir de la plantilla incluida y después lo editas para que coincida con los puestos que buscas.
Ejecuta este comando desde la carpeta del proyecto:
cp templates/portals.example.yml portals.ymlAbre portals.yml en cualquier editor de texto. Los pasos siguientes recorren las tres secciones que editas primero: el filtro de títulos, las empresas a seguir y las consultas de búsqueda.
Configura tu filtro de títulos
El filtro de títulos es la forma en que el escáner decide si merece la pena mostrarte una oferta. Compara el título del puesto con dos listas de palabras clave.
Busca la sección title_filter cerca del principio del archivo:
title_filter:
positive:
- "AI"
- "ML"
- "Product Manager"
negative:
- "Junior"
- "Intern"
seniority_boost:
- "Senior"
- "Staff"
- "Lead"Sustituye la lista positive por palabras clave que coincidan con los puestos que buscas. Una oferta debe coincidir con al menos una palabra clave de esta lista para pasar el filtro. La comprobación no distingue mayúsculas de minúsculas, así que "AI" también captura "ai engineer".
Sustituye la lista negative por palabras clave que descarten una oferta. Si alguna de ellas aparece en el título, la oferta se omite — aunque haya coincidido con una palabra clave positiva.
Deja seniority_boost tal cual a menos que quieras añadir o quitar niveles de seniority. Estas palabras clave no filtran nada — solo hacen que las ofertas que coinciden aparezcan más arriba en los resultados.
Ejemplo: si buscas puestos de ingeniería Rails, tu filtro podría tener este aspecto:
title_filter:
positive:
- "Rails"
- "Ruby"
- "Full Stack"
- "Backend"
negative:
- "Junior"
- "Intern"
- "PHP"
- "Java"
seniority_boost:
- "Senior"
- "Staff"
- "Lead"Consejo
Empieza con una lista positive pequeña, de tres a cinco palabras clave. Siempre puedes añadir más después. Una lista larga hace más difícil ver por qué una oferta pasó el filtro o no.
Añade empresas a seguir
La sección tracked_companies es una lista de empresas concretas que quieres que el escáner compruebe en cada ejecución. El escáner va directamente a la página de empleo de cada empresa y lee los puestos abiertos.
Busca la sección tracked_companies cerca del final del archivo. Cada entrada tiene este aspecto:
tracked_companies:
- name: Anthropic
careers_url: https://job-boards.greenhouse.io/anthropic
api: https://boards-api.greenhouse.io/v1/boards/anthropic/jobs
enabled: true
- name: OpenAI
careers_url: https://openai.com/careers
enabled: truePara añadir una empresa, copia una entrada existente y cambia los valores:
| Campo | Qué poner |
|---|---|
name | El nombre de la empresa tal y como quieres que aparezca en los resultados |
careers_url | La URL directa a la página de ofertas de empleo de la empresa |
api | Opcional. La URL de la API de Greenhouse si la empresa usa Greenhouse. Omítelo si no estás seguro. |
enabled | Ponlo a true para incluir la empresa o a false para omitirla sin borrar la entrada. |
Para encontrar la careers_url de una empresa, ve a la web de la empresa, haz clic en Careers o Jobs, y copia la URL de la página que lista los puestos abiertos. Esa es la URL que debes usar.
Para desactivar una empresa sin borrarla, pon enabled: false:
- name: Stripe
careers_url: https://stripe.com/jobs/search
enabled: falseNota
Toda empresa en tracked_companies debe tener una careers_url. Sin ella, el escáner no tiene ninguna página que visitar y omitirá esa entrada.
Revisa las consultas de búsqueda
La sección search_queries ejecuta búsquedas web más amplias para encontrar puestos en empresas que no están en tu lista de seguimiento. La plantilla incluye muchas consultas ya preparadas.
No necesitas cambiar esta sección para empezar. Las consultas ya preparadas cubren los principales portales de empleo, incluyendo Greenhouse y Ashby, entre otros.
Cuando estés listo para personalizarlas, cada consulta tiene este aspecto:
search_queries:
- name: Greenhouse — Rails Engineer
query: 'site:job-boards.greenhouse.io "Rails Engineer" OR "Ruby on Rails" remote'
enabled: truePara desactivar una consulta que no necesites, pon enabled: false. Para añadir una nueva, copia una entrada existente, dale un name nuevo y actualiza el texto de query.
Elige el idioma de las ofertas (opcional)
Algunos portales de empleo publican la misma oferta en varios idiomas. Si solo te presentas a ofertas en algunos de ellos, indica esos idiomas en orden de preferencia:
preferred_languages: [en]Cuando una oferta tiene versiones en esos idiomas, el escaneo conserva la del idioma que aparece primero en tu lista; si no, conserva la versión predeterminada de la oferta. Es un orden de preferencia, no un filtro: no se descarta ninguna oferta y sigues obteniendo una fila por oferta. Las variantes regionales cuentan como un mismo idioma, así que en-GB es en. Para fijar el idioma de una sola empresa, añade el parámetro propio del portal a su careers_url: ?language=xx en Personio, ?lang=xx en Recruitee.
Ejecuta un escaneo
Hay dos formas de ejecutar un escaneo. Usa la que encaje con lo que necesitas.
Opción A — Ejecuta el script directamente
npm run scanEjecútalo desde la carpeta del proyecto. El script lee portals.yml, consulta la API de cada empresa directamente y escribe las ofertas nuevas en data/pipeline.md. No consume tokens de IA y tarda unos 30 segundos.
Esta opción funciona con cualquier empresa cuya página de empleo use una plataforma para la que el escáner tiene un provider integrado: Greenhouse, Ashby y Lever, además de decenas de otros sistemas de seguimiento de candidatos (ATS) y portales de empleo como Workable, Workday y SmartRecruiters. La lista completa está en SUPPORTED_JOB_BOARDS.md. Las empresas sin un provider compatible se omiten, y el escaneo indica cuántas son.
Previsualiza los resultados antes de guardarlos:
npm run scan -- --dry-runEsto ejecuta el escaneo completo pero no escribe nada en disco. Úsalo para comprobar la configuración de tus filtros antes de guardar resultados.
Escanea una sola empresa:
npm run scan -- --company AnthropicSustituye Anthropic por cualquier nombre de empresa de tu lista tracked_companies. La coincidencia no distingue mayúsculas de minúsculas.
Escanea sitios de empleo de Dayforce:
Los sitios de empleo de Dayforce (Ceridian), en jobs.dayforcehcm.com, bloquean las peticiones web simples, así que npm run scan no puede leerlos. En su lugar, un script aparte abre una sesión real de navegador para ellos, lo que lo hace más lento que el escaneo principal. Añade los portales en dayforce_boards dentro de portals.yml, una entrada por empresa con su name y su tenant (el código de la empresa en la dirección de Dayforce); templates/portals.example.yml muestra el formato. Después ejecuta:
npm run scan:dayforceLas ofertas nuevas van a data/pipeline.md, igual que en el escaneo principal. Añade -- --dry-run para previsualizar sin guardar, -- --tenant <tenant> para escanear un solo portal, o -- --debug para guardar una captura de pantalla de cada portal en output/. Si un portal muestra una verificación anti-bots, el script lo omite; nunca intenta saltársela.
Opción B — Ejecuta el escaneo con IA dentro de Claude Code
Abre Claude Code en la carpeta del proyecto y escribe:
/career-ops scanEsta versión visita la página de empleo de cada empresa directamente usando un navegador, así que funciona incluso con empresas que no tienen API pública. También ejecuta las search_queries de tu portals.yml para encontrar puestos en empresas que no están en tu lista de seguimiento.
Usa esta opción cuando:
- Una empresa de tu lista usa una plataforma para la que el script no tiene provider, así que el escaneo con el script la omite
- Quieres descubrir empresas nuevas, no solo comprobar las conocidas
- El escaneo con el script pasó por alto algo que esperabas ver
Si el script pasó por alto una oferta que encontraste tú, pregúntale primero por qué:
node coverage-check.mjs <url> --company "<company>" --title "<job title>"Lee tu portals.yml y el historial de escaneos sin conectarse a internet, explica por qué se pasó por alto la oferta (la empresa no está en seguimiento, su entrada está desactivada, ningún provider lee su sitio de empleo, o un filtro de títulos o de ubicación la descartó) y propone el único cambio que la habría detectado. Nunca edita portals.yml por ti.
Consejo
La Opción B consume tokens del modelo de IA y tarda más que el script. Que esos tokens se cobren a una clave de API o cuenten para tu suscripción depende de cómo esté configurado tu CLI (consulta las preguntas frecuentes). Para una comprobación rápida diaria, la Opción A es más rápida.
Lee el resultado del escaneo
Cuando el escaneo termina, verás un resumen como este:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Portal Scan — 2026-04-13
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Companies scanned: 42
Total jobs found: 318
Filtered by title: 291 removed
Duplicates: 4 skipped
New offers added: 23
New offers:
+ Anthropic | AI Engineer | San Francisco, CA
+ ElevenLabs | Solutions Architect | Remote
...
→ Run /career-ops pipeline to evaluate new offers.Esto es lo que significa cada línea:
| Línea | Qué te dice |
|---|---|
| Companies scanned | Cuántas empresas de tracked_companies se comprobaron |
| Total jobs found | Todos los puestos abiertos vistos en esas empresas, antes de aplicar ningún filtro |
| Filtered by title | Ofertas eliminadas porque el título no coincidía con tu title_filter |
| Duplicates skipped | Ofertas que ya estaban en tu pipeline o tracker — no se añaden de nuevo |
| New offers added | Ofertas que pasaron todos los filtros y son nuevas para ti |
Si New offers added es 0, busca primero este aviso en la salida del escaneo:
⚠️ 1 target(s) returned zero jobs without a successful HTTP response: AcmeSignifica que el portal de esa empresa nunca respondió correctamente, así que ese cero no demuestra que no tenga ofertas. La empresa queda registrada como unverified_zero en data/portal-health.tsv y cuenta para su racha de fallos. Revisa ese portal antes de cambiar tus filtros. Un portal lento también puede quedarse sin tiempo antes de responder: el escáner espera 10 segundos por petición de forma predeterminada, y CAREER_OPS_HTTP_TIMEOUT_MS=30000 npm run scan le da 30.
Si no aparece ese aviso, puede que tu filtro de títulos sea demasiado estricto. Prueba a añadir una palabra clave a tu lista positive y vuelve a ejecutar el escaneo.
Adónde van las ofertas nuevas: cada oferta nueva se añade como una línea en data/pipeline.md. Esa es la lista de ofertas pendientes de evaluar.
Qué hace data/scan-history.tsv: cada URL que el escáner ve — tanto si se añadió, se filtró o se omitió — queda registrada aquí. Así es como el escáner evita mostrarte la misma oferta dos veces en escaneos futuros. Una excepción son las ofertas que descartó tu location_filter o tu max_posting_age_days en portals.yml. Se registran como skipped_location o skipped_age y pueden volver a aparecer cuando cambies ese ajuste. No necesitas editar este archivo.
Evalúa las ofertas nuevas de un escaneo
Después de que un escaneo añada ofertas nuevas a data/pipeline.md — tu lista de ofertas de empleo pendientes — ejecuta el comando pipeline para evaluar cada una contra tu perfil. Este paso usa Claude para leer la descripción del puesto, compararla con tu cv.md y modes/_profile.md, y producir un resumen con puntuación para cada puesto.
Abre Claude Code en la carpeta del proyecto y escribe:
/career-ops pipelineClaude lee cada URL pendiente de data/pipeline.md, visita cada oferta publicada y la evalúa. Los resultados llegan por lotes. Cada lote muestra una tabla como esta:
Lote 1 terminado (Anthropic, ElevenLabs, Mistral):
| # | Empresa | Puesto | Puntuación | Legitimidad |
|---|---|---|---|---|
| 024 | Anthropic | AI Engineer | 4.8/5 | High Confidence |
| 025 | ElevenLabs | Solutions Architect | 4.1/5 | High Confidence — fast-growing |
| 026 | Mistral AI | Product Manager | 3.2/5 | Proceed w/ Caution — role closed |
Esto es lo que significa cada columna:
| Columna | Qué te dice |
|---|---|
| # | El número del informe. Úsalo para encontrar el informe completo en reports/ — por ejemplo, el informe 024 es reports/024-anthropic-2026-04-13.md |
| Puntuación | Cómo de bien encaja el puesto con tu perfil, de 1 a 5 |
| Legitimidad | Si la oferta parece real y activa. "High Confidence" significa que la oferta está activa y los detalles cuadran. "Proceed w/ Caution" significa que algo levantó una alerta — lee la nota que la acompaña. |
Para leer la evaluación completa de un puesto, tienes dos opciones:
- Abre el archivo del informe directamente — encuéntralo en la carpeta
reports/usando el número de la tabla. - Usa el dashboard — ejecuta
./dashboard/career-dashboarddesde la carpeta del proyecto para navegar por todos tus informes en una interfaz de terminal. Puedes filtrar por puntuación y estado, y abrir cualquier informe sin salir del terminal.
Qué hacer después
Cuando /career-ops pipeline termina, cada oferta tiene una puntuación de 1 a 5. Puedes encontrar el informe completo de cualquier puesto en la carpeta reports/. La puntuación muestra cómo de bien encaja el puesto con tu perfil.
Usa la puntuación como punto de partida:
| Puntuación | Acción recomendada |
|---|---|
| 4.5 o más | Encaje fuerte. Ejecuta /career-ops apply de inmediato. |
| 4.0 – 4.4 | Buen encaje. Ejecuta /career-ops apply. También puedes ejecutar /career-ops contacto primero para contactar con alguien del equipo antes de enviar tu candidatura. |
| 3.5 – 3.9 | Podría ir en cualquier dirección. Ejecuta /career-ops deep para saber más antes de decidir. |
| Menos de 3.5 | Descártala salvo que tengas una razón concreta para presentarte. |
Esto es lo que hace cada comando:
/career-ops apply— Abre el formulario de solicitud y escribe respuestas adaptadas a tu perfil. Se detiene antes de enviar para que puedas revisarlo todo primero./career-ops contacto— Encuentra a un hiring manager o miembro del equipo en LinkedIn y redacta un mensaje corto de contacto para que lo envíes tú./career-ops deep— Investiga la empresa y el puesto en profundidad. Úsalo cuando estés indeciso y quieras más información antes de decidir./career-ops tracker— Muestra el estado de cada puesto de tu pipeline. Ejecútalo siempre que quieras ver cómo van las cosas.
Consejo
No tienes que ir en orden. Si un puesto puntúa 4.8 pero nunca has oído hablar de la empresa, ejecuta /career-ops deep primero. Los comandos funcionan por sí solos — usa el que encaje con tu situación.
¿Merece la pena aplicar a esta oferta?
Decide antes de aplicar. career-ops puntúa una oferta de 1 a 5 según tu CV y tus objetivos, te muestra su razonamiento y te deja la decisión a ti.
Presentar una candidatura
Usa career-ops para rellenar formularios de candidatura con respuestas adaptadas a tu perfil y al puesto que buscas.