

# Como coletar listagens de vagas do Naukri de acesso público por uma API

Use a API da Apify para executar uma busca pública do Naukri. Defina um número máximo fixo de linhas salvas. Espere até essa execução terminar. Leia as linhas salvas em páginas. Guarde cada ID e cada URL de vaga da fonte com o comprovante da execução. Um comprovante é a prova salva do que a execução fez. Você recebe a amostra do Naukri que pediu. Uma lista completa de vagas da Índia está fora desta amostra.

Uma API é um pedido do seu programa a outro serviço. A Apify é o serviço hospedeiro que inicia o trabalho e guarda o resultado. Um Actor é um programa hospedado de coleta de dados. O [Naukri Jobs Actor](https://apify.com/chronometrica/naukri-jobs-scraper) é o Actor deste método. Ele lê páginas públicas do Naukri. Ele não usa um login do Naukri. Uma Task é uma entrada salva predefinida. A [Task pública atual](https://apify.com/chronometrica/naukri-jobs-scraper/examples/naukri-jobs-api-dataset) é só uma entrada inicial. Ela não analisa vagas para você. O Actor salva linhas da fonte. Você confere o comprovante e escolhe as linhas para o seu projeto.

Este caminho usa a API da Apify. Ele não é uma API oficial do Naukri. Ele não é um banco de dados privado de empresa. Ele não é um índice completo de vagas da Índia. Ele mostra este único Actor público.

## 1. Defina uma busca e um limite de linhas

Anote as linhas que você quer antes de começar. Escolha um cargo. Escolha uma cidade da Índia ou deixe a cidade vazia. Escolha quão recente a publicação da fonte deve ser. Escolha um número máximo pequeno de linhas salvas.

O Actor público atual aceita esta entrada:

- `searchTerm` recebe uma palavra-chave em cada linha.
- `location` é opcional.
- `maxItems` é o limite de linhas. Ele limita as linhas salvas da execução inteira. O limite não é separado para cada linha de palavra-chave. Se você omitir esse campo, o limite numérico deixa de existir. Sempre envie um número neste método.
- `postedWithinDays` é texto. Use "0", "1", "3", "7", "15" ou "30". O texto "0" significa qualquer data de publicação.
- `experienceYears` é opcional. É um número inteiro de 0 a 30. Fresher significa pouca ou nenhuma experiência anterior de trabalho nessa configuração de busca. O valor 0 pede a configuração de busca fresher. Este método não avalia a adequação à vaga.
- `sortBy` é `relevance` ou `date`.
- `excludeCompanies` é opcional. O exemplo abaixo não o usa.
- `searchDepth` é `standard`, `extended` ou `deep`. `standard` é a primeira verificação estreita. Ela lê menos páginas da fonte do que as outras duas. Este método não precisa de uma busca mais profunda.

A Task pública atual guarda `searchTerm` "software engineer", `postedWithinDays` "7", `sortBy` "date" e `searchDepth` "standard". Coloque o seu cargo em `searchTerm`. Coloque a sua cidade em `location` se quiser uma cidade. Defina o seu próprio `maxItems`.

Um controle conferido usou valores diferentes. Ele usou uma palavra-chave, "software engineer". Ele não enviou local. Ele usou `postedWithinDays` "0", `maxItems` 2, `sortBy` "relevance" e `searchDepth` "standard". A execução salvou dois IDs distintos de vaga do Naukri, cada um contado uma vez. Cada linha tinha um título, um nome de empresa e um local. Cada linha tinha um `jobUrl` direto do Naukri. Cada `sourceUrl` correspondia à consulta pedida. `source` era naukri.com. Cada linha tinha `observedAt`. As duas linhas incluíam `descriptionText`. As duas linhas incluíam `experienceRaw`. Os dois intervalos numéricos eram 0-5 e 0-2. Esses zeros são anos mínimos observados. Eles não são campos vazios. O controle não enviou `experienceYears`. Ele não prova que um filtro fresher foi aplicado.

A execução verificada terminou com sucesso. O registro OUTPUT dela mostrou estes valores conhecidos. `rowsSaved` era 2. `requestedMaxItems` era 2. `pagesRequested` era 1. O comprovante informou 20 registros candidatos de listagem vistos. `failedRequests` era 0. `blockedRequests` era 0. `stopReason` era `max_items_reached`. A execução atingiu o limite. Duas linhas salvas não são todas as vagas correspondentes. A verificação não informou `searchesQueued`, `searchesFinished` nem `sourceStates`. Esses três valores são desconhecidos. Desconhecido não é o mesmo que 0.

Uma linha salva pode incluir os campos abaixo.

- `schemaVersion`
- `jobId`
- `title`
- `companyName`
- `location`
- `experienceRaw`
- `experienceMinYears`
- `experienceMaxYears`
- `skills`
- `descriptionText`
- `postedAt`
- `postedAtRaw`
- `jobUrl`
- `searchTerm`
- `searchLocation`
- `sourceUrl`
- `pageNumber`
- `rankOnPage`
- `status`
- `statusReason`
- `source`
- `observedAt`

Um valor opcional pode estar ausente. Um valor ausente continua desconhecido. Ele não é um zero. `descriptionText` pode estar presente e ainda assim omitir parte do texto do empregador. Também pode omitir um requisito. `postedAt` e os campos de experiência são o que a fonte mostrou. Eles não são uma promessa de que o empregador vai contratar. `observedAt` é o momento em que o Actor viu a linha. Não é o momento em que o Naukri publicou a vaga pela primeira vez. Mantenha esses dois momentos separados.

`searchTerm`, `searchLocation` e `observedAt` pertencem à linha bruta da fonte. Se você adicionar depois a sua própria coluna de consulta, você criou essa coluna. Ela não é um campo da fonte chamado query.

## 2. Inicie a execução e guarde o ID da execução

Use a sua própria conta da Apify. Guarde o token no local seguro que o seu projeto já usa para segredos. Um token é um segredo que prova que a chamada pertence à sua conta. Mantenha um token real fora de artigos. Mantenha-o fora do código do navegador. Mantenha-o fora de logs. Mantenha-o fora de uma imagem de URL. Esta leitura pública não precisa de um login do Naukri.

A chamada de início retorna informações sobre a execução. Ela não retorna linhas de vaga. Uma execução é um início do Actor. Envie a entrada como JSON. JSON é um formato de texto para dados estruturados. Inclua o cabeçalho `Content-Type: application/json`. Envie o token no cabeçalho `Authorization`. Escreva `Bearer`, um espaço e depois o token. O corpo abaixo é uma entrada original de ensino. Não é um resultado ao vivo.

```http
POST https://api.apify.com/v2/acts/chronometrica~naukri-jobs-scraper/runs
Authorization: Bearer <APIFY_TOKEN>
Content-Type: application/json

{
  "searchTerm": "data analyst",
  "location": "Bengaluru",
  "maxItems": 2,
  "postedWithinDays": "7",
  "sortBy": "date",
  "searchDepth": "standard"
}
```

2. Inicie a execução e guarde o ID da execução

Este corpo pede os dados do cargo data analyst. Ele limita o local a Bengaluru. Ele salva no máximo 2 linhas. Ele pede publicações dos últimos 7 dias. Ele ordena por data. Ele usa a profundidade standard. A [documentação de início da execução](https://docs.apify.com/api/v2/actors-runs-post) descreve este endpoint. A mesma API permite definir um tempo limite e um limite de cobrança. Um limite de cobrança interrompe a execução no limite de custo que você escolhe. Defina os dois limites na primeira execução. Este artigo não informa preço.

Da resposta, salve `data.id`. Esse é o ID da execução. Salve também a entrada e as opções que o serviço armazenou. O ID da execução, o ID do dataset e o ID do armazenamento são três valores diferentes. Mantenha-os distintos.

## 3. Espere um estado concluído

Leia a execução com o mesmo cabeçalho privado. Espere um tempo curto entre as leituras. Pare quando o status for terminal. Um status terminal é um status concluído. Os valores concluídos são `SUCCEEDED`, `FAILED`, `TIMED-OUT` e `ABORTED`.

```http
GET https://api.apify.com/v2/actor-runs/<RUN_ID>
Authorization: Bearer <APIFY_TOKEN>
```

3. Espere um estado concluído

Salve `status`, `buildId`, `startedAt`, `finishedAt`, `defaultDatasetId` e `defaultKeyValueStoreId`. `SUCCEEDED` significa que o Actor terminou. Não significa que a fonte foi coberta por completo. `FAILED`, `TIMED-OUT` e `ABORTED` exigem uma análise antes de você confiar nas linhas. A [documentação de status da execução](https://docs.apify.com/api/v2/actor-run-get) descreve esta leitura.

## 4. Leia o comprovante OUTPUT

OUTPUT é o registro de resumo do Actor. Leia-o no armazenamento de chave-valor. Um armazenamento de chave-valor guarda registros nomeados da execução. Use `defaultKeyValueStoreId` como o ID do armazenamento.

```http
GET https://api.apify.com/v2/key-value-stores/<STORE_ID>/records/OUTPUT
Authorization: Bearer <APIFY_TOKEN>
```

4. Leia o comprovante OUTPUT

Leia estes campos:

- `rowsSaved` é o número de linhas armazenadas.
- `requestedMaxItems` é o limite que você pediu.
- `searchesQueued` é o trabalho de busca colocado na fila.
- `searchesFinished` é o trabalho de busca que terminou.
- `pagesRequested` é o número de páginas da fonte pedidas. Uma página da fonte é uma página de resultados do Naukri. Não é uma leitura do dataset salvo.
- `blockedRequests` é o número de pedidos à fonte que foram bloqueados.
- `failedRequests` é o número de pedidos à fonte que falharam.
- `sourceStates` diz como a fonte terminou.
- `stopReason` diz por que o Actor parou.

Se `rowsSaved` for igual a `requestedMaxItems` e `stopReason` for `max_items_reached`, o limite interrompeu a execução. As linhas ainda podem ajudar. Elas não são a busca completa. Um 0 contado significa que o Actor informou nenhum. Um campo ausente é desconhecido. Não transforme desconhecido em 0.

Use `sourceStates` antes de explicar um arquivo vazio. Um resultado vazio pode significar que a fonte não retornou linhas. Também pode significar que a fonte não foi alcançada. Esses dois desfechos são diferentes. Se `failedRequests` ou `blockedRequests` for maior que 0, não trate a cidade como vazia. Se `sourceStates` estiver ausente, o desfecho da fonte é desconhecido. Guarde o comprovante nos dois casos.

## 5. Leia o dataset depois que a execução terminar

Um dataset é o conjunto salvo de itens em linha. Leia-o depois que a execução estiver terminal. Um dataset que ainda está crescendo não é estável. Termine a execução primeiro. Se você precisar das linhas antes do fim, planeje esse caso de propósito. Não trate uma página do meio como o conjunto final.

```http
GET https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=json&offset=0&limit=2
Authorization: Bearer <APIFY_TOKEN>
```

5. Leia o dataset depois que a execução terminar

A resposta é um array JSON. `offset` é o número de linhas salvas a pular. `limit` é o número de linhas a retornar nesta leitura. Esta leitura é uma página do dataset. Não é uma página da fonte do Naukri. A [documentação de itens do dataset](https://docs.apify.com/api/v2/dataset-items-get) descreve esta chamada. Conte as linhas do array. Some essa contagem a `offset`. Leia de novo. Guarde um comprovante pequeno de cada leitura. O comprovante precisa do offset, do limit, da contagem retornada e de qualquer erro de leitura.

Para um dataset concluído de duas linhas, a primeira leitura pode retornar duas linhas. A leitura seguinte usa offset 2 e limit 2. Ela pode retornar um array vazio. O array vazio tem uma contagem retornada de 0. Esse 0 significa que esta página não tinha mais linhas. Não significa que as linhas anteriores desapareceram. As linhas lidas são 2. Se `rowsSaved` for 2, essas contagens coincidem.

Se uma leitura do dataset falhar, guarde essa falha no comprovante. Não substitua uma leitura que falhou por um array vazio. As linhas não lidas continuam desconhecidas.

## 6. Salve a identidade antes de filtrar

Armazene a linha bruta. Armazene `jobId` como texto. Mantenha os zeros à esquerda. Um programa que armazena o ID como número pode descartar esses zeros. Adicione o prefixo da fonte `naukri:` ao ID da vaga. Esse prefixo é o namespace. Um namespace mostra qual site criou o ID. Outro site de vagas pode usar os mesmos dígitos para uma vaga diferente. O namespace dele permanece separado.

Armazene também `jobUrl`, `sourceUrl`, o `searchTerm` bruto, o `searchLocation` bruto, `observedAt` e o ID da execução. Confira se a identidade está presente. Confira os tipos que você espera. Se `jobId` estiver ausente, a linha permanece não resolvida. Não resolvida significa que você ainda não pode ligar a linha a uma vaga da fonte. Não crie uma chave da fonte para ela.

Uma observação é um registro salvo de uma linha da fonte vista uma vez. A mesma listagem em uma execução posterior é uma nova observação de uma vaga da fonte já conhecida. Ela não é automaticamente uma nova vaga aberta. Mantenha [linhas duplicadas](/pt-BR/articles/vagas-duplicadas-e-possiveis-republicacoes/) visíveis. Mantenha visível um conflito entre duas linhas para uma mesma identidade. Depois aplique as regras do seu projeto. Mantenha as linhas com falha no comprovante quando selecionar as linhas úteis.

O significado de salário está fora deste método. Regras sobre adequação à vaga estão fora deste método. Este método não envia candidaturas. Um agendamento posterior é uma escolha nova. Este artigo não inicia uma coleta repetida.

## 7. Organize um comprovante concluído

A história desta seção é ficção original. Não é saída de um teste ao vivo. Não é um resultado de produto. Os IDs, as URLs e os horários foram inventados para o ensino. Não acesse estas URLs da história nem envie pedidos a elas. Não trate as linhas como linhas reais do Naukri.

A execução fictícia R1 usa o corpo de ensino da seção de início. O pedido da história é um POST para `https://api.apify.com/v2/acts/chronometrica~naukri-jobs-scraper/runs` com `Content-Type: application/json`. A resposta de início da história inclui `data.id` "R1". Ela não inclui linhas de vaga.

R1 termina depois com o status `SUCCEEDED`. O ID do dataset da história é D1. O ID do armazenamento da história é K1. O registro salvo da execução na história tem esta forma:

```json
{
  "data": {
    "id": "R1",
    "status": "SUCCEEDED",
    "buildId": "fiction-build",
    "startedAt": "2026-04-01T09:00:00Z",
    "finishedAt": "2026-04-01T09:05:00Z",
    "defaultDatasetId": "D1",
    "defaultKeyValueStoreId": "K1"
  }
}
```

7. Organize um comprovante concluído

O registro OUTPUT da história é:

```json
{
  "rowsSaved": 2,
  "requestedMaxItems": 2,
  "failedRequests": 0,
  "stopReason": "max_items_reached"
}
```

7. Organize um comprovante concluído

Nesta história, `blockedRequests`, `searchesQueued`, `searchesFinished`, `pagesRequested` e `sourceStates` não são informados nesse registro OUTPUT. Deixe-os desconhecidos. Não escreva 0 para eles. `failedRequests` é 0 porque a história diz que não houve pedidos com falha. Esse 0 é conhecido.

A primeira leitura do dataset usa offset 0 e limit 2. Ela retorna este array:

```json
[
  {
    "jobId": "000101",
    "jobUrl": "https://www.naukri.com/example-fiction/000101",
    "sourceUrl": "https://www.naukri.com/example-fiction/search",
    "searchTerm": "data analyst",
    "searchLocation": "Bengaluru",
    "source": "naukri.com",
    "observedAt": "2026-04-01T09:04:00Z"
  },
  {
    "jobId": "000102",
    "jobUrl": "https://www.naukri.com/example-fiction/000102",
    "sourceUrl": "https://www.naukri.com/example-fiction/search",
    "searchTerm": "data analyst",
    "searchLocation": "Bengaluru",
    "source": "naukri.com",
    "observedAt": "2026-04-01T09:04:00Z"
  }
]
```

7. Organize um comprovante concluído

A contagem retornada é 2. Estas linhas da história não incluem `postedAt`. O horário de publicação é desconhecido. Não é 0. A leitura seguinte usa offset 2 e limit 2. Ela retorna:

```json
[]
```

7. Organize um comprovante concluído

A contagem retornada é 0. As linhas lidas são 2. `rowsSaved` é 2. As contagens coincidem: 2 é igual a 2. Os IDs conhecidos da fonte são `naukri:000101` e `naukri:000102`. São dois IDs conhecidos. Os zeros à esquerda permanecem no texto. As duas linhas mantêm a URL da fonte da história, os campos brutos da consulta e `observedAt`. O limite significa duas listagens observadas. Não significa que Bengaluru tenha só duas vagas abertas.

Uma parte posterior da mesma ficção é a execução R2. A história diz que R2 retorna `000102` de novo e `000103`. Ela não fornece um registro OUTPUT separado. Não invente `stopReason` nem contagens de pedidos para R2. As duas linhas da história são:

```json
[
  {
    "jobId": "000102",
    "jobUrl": "https://www.naukri.com/example-fiction/000102",
    "sourceUrl": "https://www.naukri.com/example-fiction/search",
    "searchTerm": "data analyst",
    "searchLocation": "Bengaluru",
    "source": "naukri.com",
    "observedAt": "2026-04-08T09:04:00Z"
  },
  {
    "jobId": "000103",
    "jobUrl": "https://www.naukri.com/example-fiction/000103",
    "sourceUrl": "https://www.naukri.com/example-fiction/search",
    "searchTerm": "data analyst",
    "searchLocation": "Bengaluru",
    "source": "naukri.com",
    "observedAt": "2026-04-08T09:04:00Z"
  }
]
```

7. Organize um comprovante concluído

Armazene as duas linhas de R2 como novas observações. Só `naukri:000103` é um novo ID conhecido da fonte. `naukri:000102` já é conhecido.

A conta usa contagens simples:

- Observações de R1 = 2.
- Observações de R2 = 2.
- Todas as observações = 2 + 2 = 4.
- IDs conhecidos depois de R1 = 2.
- Novo ID conhecido em R2 = 1.
- ID conhecido repetido em R2 = 1.
- IDs conhecidos depois das duas execuções = 2 + 1 = 3.
- IDs não resolvidos nestas quatro linhas = 0, porque cada linha da história tem um `jobId`.

Quatro observações não são quatro vagas. Três IDs conhecidos da fonte não são três vagas de empregador. A história não tem uma correspondência separada entre empregadores. Ela não prova três vagas abertas.

| Verificação | Contagem |
| --- | --- |
| Observações de R1 | 2 |
| Observações de R2 | 2 |
| Todas as observações | 4 |
| IDs conhecidos da fonte | 3 |
| Novo ID conhecido em R2 | 1 |
| ID conhecido repetido em R2 | 1 |
| IDs não resolvidos nas quatro linhas | 0 |
| Vagas de empregador comprovadas | não mostrado |

Uma verificação fictícia extra não faz parte dessas quatro linhas. Se um download repetir `000102` na mesma página, registre a duplicata. Não crie uma segunda identidade. O ID conhecido continua `naukri:000102`. Se outra linha da história tiver um título, mas não tiver `jobId`, some 1 a não resolvidos. Não crie uma chave como `naukri:unknown`.

Entregue ao seu projeto as linhas brutas, os IDs das execuções e este comprovante. Acrescente uma nota curta de que as linhas vieram de páginas públicas do Naukri por meio deste Actor. Acrescente o horário em `observedAt`. Então o projeto pode usar a amostra. O limite não é um mercado completo.

## Próxima ação

Organize uma execução com limite e salve o comprovante que liga cada linha à sua fonte. Faça isso antes de usar as linhas. Comece pelo [Naukri Jobs Actor](https://apify.com/chronometrica/naukri-jobs-scraper) e pela [Task pública atual](https://apify.com/chronometrica/naukri-jobs-scraper/examples/naukri-jobs-api-dataset).

## Fontes e leituras adicionais

- [Naukri Jobs Actor](https://apify.com/chronometrica/naukri-jobs-scraper)
- [Task pública atual do Naukri Jobs](https://apify.com/chronometrica/naukri-jobs-scraper/examples/naukri-jobs-api-dataset)
- [Iniciar uma execução de Actor](https://docs.apify.com/api/v2/actors-runs-post)
- [Obter uma execução de Actor](https://docs.apify.com/api/v2/actor-run-get)
- [Obter itens do dataset](https://docs.apify.com/api/v2/dataset-items-get)
- [Pergunta pública sobre uma API de listagem de vagas da Índia](https://www.reddit.com/r/developersIndia/comments/1szvizh/is_there_any_public_api_for_indian_job_listing/)