Como Extrair Anúncios de Emprego do Indeed: Estrutura, Blocos e a Rota SERP

O Indeed é o maior quadro de empregos na web e um sinal vivo do mercado de trabalho. Ele também está atrás do Cloudflare com nomes de classes que rodam semanalmente. Veja como extrair de forma durável — e quando pular o site completamente.

O Indeed atrai cerca de 542 milhões de visitas por mês, o que torna suas listas um dos sinais ao vivo mais limpos para o mercado de trabalho — demanda de contratação por função, faixas salariais, quais empresas estão contratando. É também um site React protegido pelo Cloudflare cujos nomes de classes CSS visíveis rodam com frequência suficiente para quebrar um scraper ingênuo em semanas. Este guia mostra como extrair anúncios de emprego do Indeed de forma durável, como paginar e desduplicar, a realidade do Cloudflare e a vertical SERP de empregos que permite pular a luta completamente.

Leia a página de busca, ancore em atributos estáveis

A unidade de dados do Indeed é a página de resultados de busca: consulta mais localização lhe dá uma página de cartões de emprego. A armadilha é selecionar nos nomes de classes com hash (coisas como eu4oa1w0) que o Indeed regenera. Ancore em vez disso nos atributos data-testid, que mudam com muito menos frequência:

import requests
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9",
}
proxies = {"http": "http://USER:PASS@gate.quantumproxies.io:8000",
           "https": "http://USER:PASS@gate.quantumproxies.io:8000"}

url = "https://www.indeed.com/jobs?q=python&l=New+York%2C+NY"
html = requests.get(url, headers=headers, proxies=proxies, timeout=30).text
soup = BeautifulSoup(html, "html.parser")

jobs = []
for card in soup.select("div.job_seen_beacon"):
    title = card.find("a", class_="jcs-JobTitle")
    company = card.find("span", attrs={"data-testid": "company-name"})
    location = card.find("div", attrs={"data-testid": "text-location"})
    jobs.append({
        "title": title.get_text(strip=True) if title else None,
        "company": company.get_text(strip=True) if company else None,
        "location": location.get_text(strip=True) if location else None,
        "jk": title["href"].split("jk=")[-1][:16] if title else None,
    })
print(len(jobs), "jobs on page 1")

Cada cartão carrega uma chave de emprego (jk) — um ID estável que você usa para desduplicar entre páginas e execuções. Armazene em jk, não na URL, porque o mesmo anúncio aparece com diferentes parâmetros de rastreamento.

Paginação e sites por país

O Indeed pagina com um parâmetro start que incrementa de 10 em 10. E não é um único site — cada país é um subdomínio: www.indeed.com para os EUA, uk.indeed.com para o Reino Unido, e assim por diante. Combine sua saída de proxy com o país que você está consultando para que a solicitação seja geograficamente coerente:

def crawl(query, location, country="www", pages=5):
    base = f"https://{country}.indeed.com/jobs"
    for start in range(0, pages * 10, 10):
        params = {"q": query, "l": location, "start": start}
        html = requests.get(base, params=params, headers=headers,
                            proxies=proxies, timeout=30).text
        # parse as above, yield rows
        yield html

# freshness filter: fromage accepts only 1, 3, 7 or 14 days
# .../jobs?q=python&l=NYC&fromage=7

Uma peculiaridade que vale a pena saber: o filtro "postado dentro de" do Indeed (fromage) só aceita 1, 3, 7 ou 14 dias — outros valores são ignorados, então construa sua lógica de atualização em torno desses intervalos.

Pipeline para extrair páginas de busca do Indeed: URL de consulta através de uma saída residencial, analisando cartões por data-testid, paginando por início e desduplicando por chave de emprego
Ancore em data-testid e na chave de emprego; pagine por incrementos de 10 e desduplique para capturar o conjunto completo de resultados.

A realidade do Cloudflare

O Indeed está atrás do Cloudflare, então um IP de datacenter com uma solicitação simples frequentemente recebe um desafio em vez de resultados. As soluções são o habitual stack anti-bot: um User-Agent de navegador coerente e conjunto de cabeçalhos, e — a maior alavanca — uma saída residencial que não está pré-avaliada como automação. Um proxy residencial se apresenta como a conexão de um usuário real, o que mantém o Cloudflare servindo a página. Quando um desafio aparece, combinar a impressão digital do navegador importa tanto quanto o IP; nosso guia sobre como passar pelo Cloudflare em 2026 cobre onde a linha está.

O atalho: a vertical SERP de empregos

Se o que você realmente quer são dados do mercado de trabalho — não o HTML do Indeed especificamente — há um caminho mais limpo. A vertical de empregos do Google agrega anúncios do Indeed e de muitos outros quadros, e uma SERP API retorna essa vertical de empregos como JSON analisado: título, empresa, localização, data de postagem e fonte, sem seletores CSS para manter e sem Cloudflare para enfrentar. Você troca algum controle de campo por um feed estruturado estável em muitos quadros de uma vez, o que para análises agregadas de contratação geralmente é o melhor negócio. É o mesmo raciocínio por trás de construir um agregador de quadros de emprego em um feed SERP em vez de um scraper por site.

Puxe a vertical de empregos como JSON limpo

Para que os dados são bons

Além de uma busca de emprego, esses dados impulsionam análises reais: benchmarking salarial por função e cidade, rastreamento de demanda por habilidades específicas ao longo do tempo, sinais de contratação de concorrentes (um rival montando uma nova equipe é um indicativo de estratégia), e enriquecimento — combinando as vagas abertas de uma empresa com dados firmográficos para prospecção. Combine com dados salariais do Glassdoor e você obtém uma visão de compensação mais completa do que qualquer fonte isolada.

Comparação entre extrair diretamente do Indeed e puxar os mesmos dados de empregos da vertical SERP do Google como JSON estruturado
Extrair do Indeed dá controle total de campo; a vertical SERP de empregos oferece JSON estruturado em muitos quadros sem manutenção de seletores.

Perguntas frequentes

Você pode legalmente extrair anúncios de emprego do Indeed?

Os anúncios de emprego são dados públicos, e coletar listas publicamente visíveis é amplamente defensável, mas os termos do Indeed restringem o acesso automatizado e você deve evitar dados pessoais e respeitar os limites de taxa. Muitas equipes contornam a questão dos termos usando a vertical de empregos SERP agregada em vez de extrair diretamente do Indeed. Esta é uma informação geral, não um conselho jurídico — reveja os termos atuais antes de um grande projeto.

Por que meu scraper do Indeed continua quebrando?

Duas razões. Primeiro, o Indeed roda seus nomes de classes CSS com hash, então seletores fixados neles falham em semanas — ancore nos atributos data-testid e na chave de emprego. Segundo, o Cloudflare começa a desafiar seu IP uma vez que é sinalizado; uma saída residencial e uma impressão digital de navegador coerente mantêm a página real carregando. Corrija ambos e o scraper estabiliza.

Como faço para extrair empregos de vários países?

O Indeed atende cada país a partir de seu próprio subdomínio (www.indeed.com, uk.indeed.com, de.indeed.com, e assim por diante). Consulte o subdomínio correto e roteie através de uma saída de proxy naquele país para que a solicitação seja geograficamente consistente — caso contrário, você pode obter resultados incompatíveis ou redirecionados. A vertical de empregos SERP também aceita um parâmetro de país se você preferir não gerenciar subdomínios.

A SERP de empregos do Google é melhor do que extrair do Indeed?

Para análises agregadas do mercado de trabalho, geralmente sim. A vertical de empregos retorna anúncios do Indeed e de muitos outros quadros como JSON estruturado, sem seletores rotativos e sem desafio do Cloudflare para lidar. Você perde alguns campos específicos do Indeed, mas ganha um feed multi-fonte estável e muito menos manutenção. Extraia diretamente do Indeed apenas quando precisar de campos que vivem nas próprias páginas do Indeed.

O Indeed recompensa a abordagem durável: ancore em atributos estáveis, desduplique por chave de emprego, pagine por dezenas e bata com um IP residencial para que o Cloudflare o sirva. E quando você só precisa do sinal do mercado de trabalho em vez do HTML exato do Indeed, a vertical SERP de empregos entrega isso a você como JSON. Escolha o caminho que corresponde ao quanto de controle de campo você realmente precisa.

Obtenha IPs residenciais que passam pelo Cloudflare