# Anapec Jobs Scraper (`scraper_guru/anapec-jobs-scraper`) Actor

Extract structured job listings, salaries, and company data from Anapec (Morocco's national employment agency).

- **URL**: https://apify.com/scraper\_guru/anapec-jobs-scraper.md
- **Developed by:** [LIAICHI MUSTAPHA](https://apify.com/scraper_guru) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 job offer results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## ANAPEC Morocco Jobs Scraper

Scrape structured job offers from **ANAPEC**, Morocco's national employment agency. Collect job titles, locations, vacancies, contracts, salaries, sectors, education, experience, employer details, and full candidate profiles.

### Features

- Extracts current ANAPEC job offers from search-result pages
- Enriches every offer from its detail page when requested
- Collects vacancies separately from job-offer count
- Captures salary, contract, education, experience, languages, and agency fields
- Handles pagination, duplicate references, retries, rate limits, and proxies
- Provides a structured dataset view and a `STATS` run summary

### Use Cases

- **Moroccan job-market analysis:** compare demand by city, sector, and role
- **Recruitment intelligence:** monitor vacancies, contracts, and qualification requirements
- **Salary research:** collect publicly listed monthly salary information
- **Skills analysis:** identify recurring education, experience, and language requirements
- **Job monitoring:** schedule recurring runs for new ANAPEC offers

### Input

| Field | Type | Default | Description |
|---|---|---:|---|
| `startUrls` | array | ANAPEC full search | Search-result URLs to collect |
| `maxItems` | integer | `100` | Maximum unique job offers |
| `includeDetails` | boolean | `true` | Enrich each offer from its detail page |
| `maxConcurrency` | integer | `12` | Parallel ANAPEC requests |
| `maxRequestsPerMinute` | integer | `480` | Request-rate ceiling |
| `proxyConfiguration` | object | Morocco Residential Proxy | Morocco-targeted proxy required from Apify Cloud |

```json
{
  "startUrls": [
    {
      "url": "https://www.anapec.org/sigec-app-rv/fr/chercheurs/resultat_recherche/tout:all"
    }
  ],
  "maxItems": 100,
  "includeDetails": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "MA"
  }
}
```

### Output

Each dataset item represents one ANAPEC job offer:

```json
{
  "jobId": "1152951",
  "reference": "TI3107261152951",
  "postedDate": "31/07/2026",
  "jobTitle": "Employe de libre service",
  "vacancies": 20,
  "company": "Marjane Market",
  "location": "TIZNIT",
  "agency": "TIZNIT / LOTFI",
  "sector": "Commerce de gros",
  "contractType": "CI",
  "monthlySalary": "3500 DHS",
  "education": "Technicien specialise",
  "experience": "6 mois - 1 an",
  "url": "https://www.anapec.org/sigec-app-rv/fr/entreprises/bloc_offre_home/1152951/resultat_recherche",
  "source": "ANAPEC",
  "scrapedAt": "2026-08-22T11:00:00.000Z"
}
```

The `STATS` record reports detected offers, pages processed, offers reserved and saved, duplicates, failures, and duration.

### How to Use

1. Open the Actor in Apify Console.
2. Keep the default ANAPEC search URL or add a filtered search URL.
3. Start with 10 to 20 items and keep detail enrichment enabled.
4. Adjust concurrency or the request-rate limit for larger runs.
5. Run the Actor and inspect the **Output** table.
6. Export results as JSON, CSV, Excel, or through the API.

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("scraper_guru/anapec-jobs-scraper").call(run_input={
    "maxItems": 100,
    "includeDetails": True,
})

for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["jobTitle"], job["location"], job["vacancies"])
```

### Pricing

This is a pay-per-event Actor. Each successfully saved job offer costs **$0.005**, or **$5 per 1,000 results**, plus the small Actor-start charge displayed by Apify. Failed requests and duplicate offers do not create paid result events.

### FAQ

**Does one result equal one open position?**\
No. One result is one job offer. Use `vacancies` to see how many positions that offer represents.

**Can I collect only listing-level fields?**\
Yes. Disable `includeDetails` for a faster snapshot without detail-page fields.

**Why are some salary or employer fields empty?**\
ANAPEC does not publish every field for every offer. Missing values are returned as null instead of being guessed.

**Can I scrape a filtered ANAPEC search?**\
Yes. Paste the filtered search-result URL into `startUrls`; pagination is handled automatically.

**Can I schedule daily monitoring?**\
Yes. Create an Apify Task with your chosen URL and limits, then attach a schedule.

**Is this the entire Moroccan labor market?**\
No. The data represents public offers visible in ANAPEC search results, not every vacancy or completed hire in Morocco.

Use the Actor lawfully, respect ANAPEC's terms, and avoid excessive request rates.

# Actor input Schema

## `startUrls` (type: `array`):

URLs to start scraping from. Usually the main search result page.

## `maxItems` (type: `integer`):

The maximum number of job listings to extract.

## `includeDetails` (type: `boolean`):

Adds sector, contract, agency, profile, education and experience fields. Disable for a faster listing-only snapshot.

## `maxConcurrency` (type: `integer`):

Maximum number of simultaneous ANAPEC requests.

## `maxRequestsPerMinute` (type: `integer`):

Rate limit used to avoid putting unnecessary load on ANAPEC.

## `proxyConfiguration` (type: `object`):

Select proxies to be used by your scraper.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.anapec.org/sigec-app-rv/fr/chercheurs/resultat_recherche/tout:all"
    }
  ],
  "maxItems": 10,
  "includeDetails": true,
  "maxConcurrency": 3,
  "maxRequestsPerMinute": 180,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "MA"
  }
}
```

# Actor output Schema

## `jobs` (type: `string`):

Job listings collected from ANAPEC.

## `runStats` (type: `string`):

Detected, reserved, saved, duplicate, and failed offer counts.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.anapec.org/sigec-app-rv/fr/chercheurs/resultat_recherche/tout:all"
        }
    ],
    "maxItems": 10,
    "includeDetails": true,
    "maxConcurrency": 3,
    "maxRequestsPerMinute": 180,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "MA"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scraper_guru/anapec-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.anapec.org/sigec-app-rv/fr/chercheurs/resultat_recherche/tout:all" }],
    "maxItems": 10,
    "includeDetails": True,
    "maxConcurrency": 3,
    "maxRequestsPerMinute": 180,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "MA",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scraper_guru/anapec-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.anapec.org/sigec-app-rv/fr/chercheurs/resultat_recherche/tout:all"
    }
  ],
  "maxItems": 10,
  "includeDetails": true,
  "maxConcurrency": 3,
  "maxRequestsPerMinute": 180,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "MA"
  }
}' |
apify call scraper_guru/anapec-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scraper_guru/anapec-jobs-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/OUyhKphjGZhOPFq3M/builds/vEjYLEuc17Qo6dEgI/openapi.json
