# StepStone & PNet Jobs Scraper (5 Countries) (`kirozhang/stepstone-jobs-scraper`) Actor

Scrape job listings from StepStone Germany, Austria, Belgium, Netherlands and PNet South Africa in one run: title, company, location, salary, home office, posting date, benefits and full description with address and coordinates.

- **URL**: https://apify.com/kirozhang/stepstone-jobs-scraper.md
- **Developed by:** [Kiro Zhang](https://apify.com/kirozhang) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 job listings

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does StepStone & PNet Jobs Scraper do?

This Actor scrapes job listings from **five StepStone-platform job boards in one run** — one input, one clean output schema:

| Board | Country | Jobs listed |
|---|---|---|
| [StepStone.de](https://www.stepstone.de) | 🇩🇪 Germany | 180,000+ — Germany's leading job board |
| [StepStone.at](https://www.stepstone.at) | 🇦🇹 Austria | All industries |
| [StepStone.be](https://www.stepstone.be) | 🇧🇪 Belgium | All industries (EN / FR / NL) |
| [StepStone.nl](https://www.stepstone.nl) | 🇳🇱 Netherlands | All industries |
| [PNet](https://www.pnet.co.za) | 🇿🇦 South Africa | South Africa's leading job board |

For every job you get the **title, company, location, salary (where published), home-office flag, posting and expiry date, benefits, labels such as "quick apply" and a text snippet**, plus — optionally — the **full job description**, employment type, industry, street address, postal code and coordinates. Export to JSON, CSV or Excel, call it via API, schedule it daily, or plug it into Make, Zapier, n8n, Google Sheets or an AI agent.

### Why use this jobs scraper?

- 🌍 **5 countries, one Actor** — Germany, Austria, Belgium, the Netherlands and South Africa with one input and one schema.
- 🔎 **Keywords + location + radius + date filters** — or paste any StepStone/PNet search URL with the site's own filters (contract type, experience level, home office, industry, company…).
- 📝 **Full descriptions on demand** — clean text and original HTML, plus address and coordinates; you only pay for descriptions that are actually returned.
- 💸 **Cheap, pay per result** — no start fee, no monthly rental.
- ⚡ **No browser** — reads the boards' own result data, 25 jobs per request, with automatic retries.
- 🧹 **Deduplicated** — jobs returned by several keywords are saved once; StepStone's off-topic "recommended" and out-of-area "regional" fillers are skipped.

#### Use cases

- **Recruitment & staffing agencies** — find new roles and hiring companies in DACH, Benelux and South Africa every morning.
- **Sales / lead generation** — companies that are hiring are companies that are growing.
- **Job boards & aggregators** — feed fresh European jobs into your site.
- **Labour-market research** — demand by region, home-office share, benefits, salary transparency.
- **AI agents & RAG** — give assistants live job data.

### How to scrape StepStone and PNet

1. Click **Try for free** / **Start**.
2. Enter **search keywords** (e.g. `data analyst`, `Pflegefachkraft`, `accountant`) — or leave empty to scrape all jobs in a location.
3. Pick one or more **job boards**, and optionally a **location**, **radius**, **posted within** and **sort order**.
4. Set **Max jobs per keyword and board**.
5. Turn on **Include full job description** if you need the job ad text.
6. Run and download your data in JSON, CSV, Excel, XML or HTML.

**Tip:** need a filter that is not in the input (contract type, experience, fully remote, industry, company…)? Apply it on the website, copy the URL of the results page and paste it into **Search URLs**.

### Input example

```json
{
    "searchTerms": ["data analyst", "software engineer"],
    "sites": ["stepstone.de", "stepstone.at", "pnet.co.za"],
    "location": "",
    "postedWithinDays": "7",
    "sortBy": "date",
    "maxJobsPerSearch": 200,
    "includeDescription": true
}
```

### Output example

```json
{
    "id": "14533047",
    "title": "Business Analyst (m/w/d) Business Intelligence",
    "company": "Hermes Germany GmbH",
    "companyId": 167268,
    "companyUrl": "https://www.stepstone.de/cmp/de/hermes-germany-gmbh-167268/jobs",
    "location": "Hamburg",
    "salary": null,
    "salaryCurrency": null,
    "homeOfficePossible": true,
    "postedAt": "2026-09-23T08:18:01+02:00",
    "expiresAt": null,
    "snippet": "In unserer IT stimmt die Chemie: mehr als 300 Spezialist*innen arbeiten daran, unsere Logistiklösungen noch smarter …",
    "benefits": ["Modernes Arbeiten & Teamspirit …", "Work-Life Balance & Flexibilität …"],
    "labels": ["QUICK_APPLY"],
    "matchType": "exact",
    "url": "https://www.stepstone.de/stellenangebote--Business-Analyst-m-w-d-Business-Intelligence-Hamburg-Hermes-Germany-GmbH--14533047-inline.html",
    "site": "stepstone.de",
    "country": "DE",
    "searchKeyword": "data analyst",
    "description": "Über uns …",
    "employmentType": "FULL_TIME",
    "industry": "Logistik, Transport & Verkehr",
    "validThrough": "2026-10-23T06:18:01.000Z",
    "city": "Hamburg",
    "postalCode": "22179",
    "latitude": 53.6,
    "longitude": 10.1,
    "scrapedAt": "2026-09-23T08:50:21.443Z"
}
```

#### Output fields

| Field | Description |
|---|---|
| `id`, `url` | Job ID on the board and a clean link to the job ad |
| `title`, `company`, `companyId`, `companyUrl`, `companyLogoUrl` | Job and employer |
| `location`, `postCode` | Location as shown in the results |
| `salary`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | Salary text and, where the board provides it, structured salary |
| `homeOfficePossible` | `true` if the ad offers home office / remote work |
| `postedAt`, `expiresAt` | Posting date and planned end of publication |
| `snippet`, `benefits`, `labels` | Teaser text, listed benefits, labels such as `QUICK_APPLY`, `NO_COVER_LETTER` |
| `matchType` | `exact` or `similar` (StepStone also returns closely related jobs for a keyword) |
| `site`, `country`, `searchKeyword`, `searchLocation`, `startUrl` | Where the job came from |
| `description`, `descriptionHtml`, `employmentType`, `industry`, `validThrough`, `streetAddress`, `city`, `region`, `postalCode`, `addressCountry`, `latitude`, `longitude` | Only with **Include full job description** |
| `descriptionError` | Why a description could not be loaded (e.g. the job has expired) |

### How much does it cost to scrape StepStone?

This Actor uses **pay-per-event** pricing — you pay only for results:

| Event | Price |
|---|---|
| Job listing saved | **$0.80 per 1,000 jobs** |
| Full job description (optional, only when returned) | **$0.70 per 1,000 descriptions** |

No start fee and no rental. Example: 1,000 jobs with full descriptions cost **$1.50**. Apify's free plan ($5 monthly credit) covers more than 3,000 such jobs every month. You can set a maximum cost per run in the run options.

### Tips & limits

- Each keyword runs on each selected board, so 3 keywords × 4 boards = 12 searches, each limited by **Max jobs per keyword and board**.
- The radius is in km.
- "Posted within 3 / 14 / 30 days" is applied exactly: the boards only offer 24 h and 7 days, so for other periods the Actor sorts by date and stops at the cut-off.
- Descriptions are read from the job ad page; expired ads return a `descriptionError` and are not charged.
- Large runs are fine but take time: roughly 1,000 jobs per 1–2 minutes without descriptions, about 30–60 descriptions per minute.

### Is it legal to scrape job listings?

This Actor only collects publicly available job advertisements — the same information any visitor sees without logging in. It does not collect personal data of candidates. Job ads can contain names or e-mail addresses of recruiters; if you process such data, make sure you have a legitimate reason and comply with GDPR and the boards' terms. When in doubt, consult a lawyer.

### FAQ & support

**Why are Totaljobs, CWJobs or IrishJobs not included?** They run on the same platform but block cloud data-center traffic, so they cannot be scraped reliably at this price. Open an issue if you need them.

**Runs are a bit slow?** The Actor deliberately paces requests (about one per second per board) and retries connections that the boards' CDN drops, so that large runs finish reliably instead of getting blocked.

**Something is not working?** Please open an issue on the **Issues** tab with your input and the run link — issues are answered quickly.

**Other scrapers by this developer:** [SEEK, JobStreet & JobsDB Jobs Scraper (8 countries)](https://apify.com/kirozhang/seek-jobstreet-jobsdb-scraper) and [Google News Scraper + Full Article Text](https://apify.com/kirozhang/google-news-scraper).

# Actor input Schema

## `searchTerms` (type: `array`):

Job titles, skills or companies, e.g. "data analyst", "Pflegefachkraft", "Buchhalter", "software engineer". Each keyword runs on every selected job board. Leave empty to scrape all jobs (optionally in a location).

## `sites` (type: `array`):

StepStone Germany, Austria, Belgium, Netherlands and PNet South Africa. All return the same clean output; each keyword runs on every selected board.

## `location` (type: `string`):

Optional city or region as you would type it on the site, e.g. "Berlin", "München", "Wien", "Brussels", "Amsterdam", "Cape Town".

## `radius` (type: `integer`):

Optional search radius in km around the location. Leave empty for the site default.

## `postedWithinDays` (type: `string`):

Only jobs posted within this many days.

## `sortBy` (type: `string`):

Order of results.

## `maxJobsPerSearch` (type: `integer`):

Maximum number of jobs to save for each keyword on each board (and for each start URL).

## `includeDescription` (type: `boolean`):

Open every job ad and add the full description (text + HTML), employment type, industry, expiry date, street address and coordinates. Charged as an extra event only when the description is returned.

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

Paste search result URLs from StepStone or PNet with the site's own filters applied (contract type, experience, home office, industry, company, …). Each URL is paged through up to "Max jobs". When used without keywords, the job boards list above is ignored.

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

Usually not needed: the Actor connects directly and automatically switches a board to residential proxy if that board starts blocking. Set a proxy here only if you want to force one.

## Actor input object example

```json
{
  "searchTerms": [
    "data analyst"
  ],
  "sites": [
    "stepstone.de"
  ],
  "postedWithinDays": "0",
  "sortBy": "relevance",
  "maxJobsPerSearch": 50,
  "includeDescription": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

# 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 = {
    "searchTerms": [
        "data analyst"
    ],
    "sites": [
        "stepstone.de"
    ],
    "maxJobsPerSearch": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("kirozhang/stepstone-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 = {
    "searchTerms": ["data analyst"],
    "sites": ["stepstone.de"],
    "maxJobsPerSearch": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("kirozhang/stepstone-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 '{
  "searchTerms": [
    "data analyst"
  ],
  "sites": [
    "stepstone.de"
  ],
  "maxJobsPerSearch": 50
}' |
apify call kirozhang/stepstone-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kirozhang/stepstone-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/3dspvhSDQR5SS4mns/builds/MUMGZYtWhqAvTOzQL/openapi.json
