Como Construir um Agregador de Vagas de Emprego: Fontes, Deduplicação e Atualização
Um bom agregador de vagas é composto por três problemas de engenharia: onde obter as listagens, como deduplicá-las e como mantê-las atualizadas. Resolva esses problemas e a raspagem se torna a parte fácil — aqui está o plano.
Um agregador de vagas de emprego é um motor de busca para anúncios de emprego: ele coleta listagens de várias fontes e as exibe em um só lugar. As partes difíceis não são os pedidos HTTP — são escolher as fontes certas, deduplicar o mesmo emprego que aparece em cinco sites e manter tudo atualizado para que você não mostre cargos preenchidos no mês passado. Acertar esses três pontos e você terá um produto defensável; errar e você terá um feed obsoleto e cheio de duplicatas que corrói a confiança. Este guia é o plano de engenharia: mistura de fontes, deduplicação canônica, atualização, o vertical de SERP de empregos e as linhas legais a respeitar. É informativo, não um conselho legal.
Fonte nível 1: endpoints públicos de ATS
Os dados de emprego mais limpos na internet não estão em quadros de empregos — estão nas páginas de carreiras das empresas alimentadas por sistemas de rastreamento de candidatos, a maioria dos quais expõe JSON estruturado. Greenhouse, Lever, Ashby, BambooHR, iCIMS, Paylocity e Workday todos fornecem listagens que você pode solicitar diretamente, sem análise de HTML. Um agregador de código aberto que puxa de todos os sete os busca em paralelo e ajusta as contagens de trabalhadores aos limites de taxa de cada plataforma — aproximadamente 50 simultâneos para Workday, 30 para Greenhouse/Lever/iCIMS, 10 para BambooHR e 5 para os limitadores mais restritivos. Este nível fornece títulos canônicos, locais, faixas salariais e URLs de aplicação diretamente do empregador, o que o torna a espinha dorsal de qualquer agregador sério.
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 para consultar, colete slugs de ATS em escala a partir de um índice da web em vez de manualmente — escanear os arquivos de URL do Common Crawl em busca de padrões de domínio de ATS pode revelar dezenas de milhares de identificadores de empresas. Essa varredura de descoberta é em si um trabalho de raspagem; direcione-a através de um pool de proxy de datacenter já que o índice é leniente e a velocidade importa mais do que a reputação do IP lá.
Fonte nível 2: o vertical de SERP de empregos
Os feeds de ATS perdem tudo o que é postado apenas em sites agregadores, quadros regionais ou na própria experiência de empregos do Google. A maneira eficiente de cobrir esse longo rabo sem raspar uma dúzia de quadros individualmente é o vertical de SERP de empregos — uma consulta estruturada que retorna os empregos que o Google exibe para um cargo e localização, já normalizados. Nossa SERP API expõe um vertical de empregos junto com notícias, imagens e compras, para que você possa puxar listagens de cargos por palavra-chave e localização como JSON e integrá-las no mesmo 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")
Execute a mesma consulta nas cidades-alvo em uma programação e você terá cobertura geográfica que nenhum feed de ATS único fornece. Como os resultados de SERP mudam por localização, direcione geograficamente cada consulta — nosso post sobre como a raspagem de SERP funciona em 2026 cobre as mecânicas de geolocalização e paginação.
Puxe o vertical de empregos da SERP API

Deduplicação por chave canônica
O mesmo emprego aparece rotineiramente no site da empresa, em dois agregadores e em um cartão de empregos do Google. Mostrá-lo quatro vezes é a maneira mais rápida de parecer quebrado. A correção padrão é uma chave canônica: normalize e faça o hash da combinação de título do emprego, empresa, localização e — quando disponível — o ID externo do emprego da fonte. Converta para minúsculas, remova pontuação e colapse espaços em branco antes de fazer o hash para que "Engenheiro de Software Sênior" e "engenheiro de software sênior" se unam.
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
Atualização é uma característica, não um pensamento posterior
A credibilidade de um quadro de empregos é sua atualização. Dois mecanismos a mantêm honesta: reobtenha cada fonte em uma programação (horária para feeds de ATS de alto volume, diária para o longo rabo), e elimine qualquer coisa que você não tenha revisto em uma janela contínua — 30 dias é um padrão sensato, mais curto para mercados de rápida movimentação. Acompanhe um carimbo de data/hora de última visualização por fonte e uma contagem diária para que você possa identificar quando uma fonte quebra silenciosamente; um agregador que monitora seu próprio volume pode abrir um alerta no momento em que os números de uma plataforma caem drasticamente. Nossa nota sobre executar raspadores como software de produção cobre agendamento, detecção de desvio e alertas.
As linhas legais a respeitar
Dados de emprego são onde a lei de raspagem se torna real, porque anúncios podem conter dados pessoais (nomes de recrutadores, detalhes de contato) e descrições detalhadas são protegidas por direitos autorais. A autoridade de proteção de dados da França multou a empresa KASPR em €240.000 por raspar dados de contato do LinkedIn sem o devido consentimento; as penalidades do GDPR podem chegar a €20 milhões ou 4% do faturamento global, e os danos por direitos autorais chegaram a $150.000 por obra em casos nos EUA. A postura mais segura é estrutural: prefira feeds de ATS autorizados e o SERP de empregos em vez de forçar a entrada em quadros protegidos por login, armazene campos factuais (título, empresa, localização) em vez de republicar descrições completas protegidas por direitos autorais, e remova dados pessoais que você não precisa. Nossa visão geral sobre legalidade da raspagem de web em 2026 e a saga de conformidade do LinkedIn vão mais a fundo.

Onde os proxies se encaixam
O nível de ATS raramente precisa de IPs residenciais, mas a varredura de descoberta, o vertical de SERP e qualquer raspagem direta de quadros precisam — Google e os maiores quadros limitam por IP e variam seus resultados por localização. Direcione esses através de proxies residenciais rotativos com rotação por solicitação e direcionamento geográfico para que cada consulta de cidade venha de uma localização correspondente. Mantenha os níveis separados: datacenter barato para o índice leniente, residencial para os alvos sensíveis.
Perguntas frequentes
O que é um agregador de vagas de emprego?
É um motor de busca para anúncios de emprego que coleta listagens de várias fontes — páginas de carreiras de empresas, plataformas de ATS, outros quadros e o SERP de empregos — normaliza-os em um único esquema, remove duplicatas e os apresenta aos candidatos em um único local pesquisável. O trabalho de engenharia está na obtenção de fontes, deduplicação e atualização, não apenas na raspagem.
Como você deduplica listagens de emprego de várias fontes?
Construa uma chave canônica normalizando e fazendo o hash do título do emprego, empresa, localização e o ID externo do emprego da fonte. Converta para minúsculas, remova pontuação e colapse espaços em branco primeiro para que variações de grafia se unam. Mantenha a primeira ocorrência e descarte as correspondências. Isso captura o mesmo cargo aparecendo no site do empregador, agregadores e empregos do Google.
É legal raspar quadros de empregos?
Depende da fonte, dos dados e da sua jurisdição. Campos de listagem factuais públicos têm menor risco do que dados pessoais ou descrições completas protegidas por direitos autorais, e contornar paredes de login aumenta a exposição ao estilo CFAA. Feeds de ATS autorizados e o SERP de empregos são as rotas mais limpas. Empresas foram multadas pesadamente por raspar dados pessoais — obtenha aconselhamento legal para uso comercial.
Quão atualizados devem ser os dados de emprego agregados?
Reobtenha fontes de alto volume como feeds de ATS a cada hora e o longo rabo diariamente, depois elimine qualquer listagem que você não tenha revisto dentro de uma janela contínua — 30 dias é um padrão comum. Acompanhe um carimbo de data/hora de última visualização por emprego e monitore o volume por fonte para que você detecte uma fonte quebrada antes que os usuários vejam cargos obsoletos.
Trate a agregação como três problemas — fontes, deduplicação, atualização — e a raspagem se torna um detalhe de suporte. Comece com feeds limpos de ATS e o vertical de SERP de empregos, deduplique em uma chave canônica, elimine agressivamente e mantenha as varreduras sensíveis em IPs residenciais rotativos. Essa é a diferença entre um produto em que as pessoas confiam e um cemitério de links mortos.