# 🧰 Kleinanzeigen Jobs Scraper - German Local Job Ads (`benthepythondev/kleinanzeigen-jobs-scraper`) Actor

Scrape job listings (Stellenangebote) from Kleinanzeigen (Germany). Parses title, employment type, salary, company, city & posting date into clean fields. Captures local / SME / mini-job inventory missing from corporate ATS boards. Filter by role, location & employment type.

- **URL**: https://apify.com/benthepythondev/kleinanzeigen-jobs-scraper.md
- **Developed by:** [Ben](https://apify.com/benthepythondev) (community)
- **Categories:** Jobs, Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 41.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 jobs

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/platform/actors/running/actors-in-store#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

## 🧰 Kleinanzeigen Jobs Scraper — Hyper-Local German Job Ads, Structured

Scrape **job listings (Stellenangebote) from Kleinanzeigen** (formerly eBay Kleinanzeigen), Germany's largest classifieds site and a huge source of **local, SME and mini-job** vacancies. It parses each ad into clean, structured fields — **title, employment type (Art der Anstellung), salary, company, city, PLZ and posting date** — capturing inventory that never appears on corporate ATS boards like Greenhouse, Lever or Ashby. Export to JSON/CSV/Excel, run on a schedule, call via API, or connect to Make, Zapier or n8n.

### 🧰 What is the Kleinanzeigen Jobs Scraper?

It turns any Kleinanzeigen jobs search into a structured dataset of hyper-local vacancies. Enter a **location** (a German postal code or a city name like `berlin` — auto-resolved to the right area), optionally a **job role** keyword (e.g. `pflegekraft`, `fahrer`, `aushilfe`), and an optional employment-type filter, then Run. The Actor walks the result pages, opens each ad to read the full description and attributes, and returns every matching job with employment type, salary (when stated), experience level, company and location. Leave the role empty to pull every job in the area. It runs through a residential German proxy by default for reliable access.

#### What data does it extract?

- **Job title** and **job category/role** (Art)
- **Employment type** (Vollzeit / Teilzeit / Minijob, from Arbeitszeit / Art der Anstellung)
- **Salary in EUR** and **salary period** (hour / month / year, parsed from Stundenlohn, Gehalt or the text)
- **Experience level** (Berufserfahrung) when stated
- **Company / employer** name (from the listing's contact section)
- **City, postal code (PLZ)** and **posting date**
- **Short description**, plus the **full description** from the detail page
- **Listing URL, image URL** and a **scrape timestamp**

### ⬇️ Input

Run it with simple fields, or paste exact search URLs for precise sub-category control:

| Field | Type | Description |
|-------|------|-------------|
| `keyword` | string | Job role to match in the title, e.g. `pflegekraft`, `fahrer`, `aushilfe küche`; empty = all jobs |
| `locationCode` | string | German PLZ (e.g. `10115`) or city name (e.g. `berlin`, `münchen`); empty = all of Germany |
| `radiusKm` | integer | Search radius around the location (0–200 km) |
| `employmentType` | string | Keep only jobs whose type contains this text, e.g. `Vollzeit`, `Teilzeit`, `Minijob` |
| `startUrls` | array | Paste exact Kleinanzeigen jobs-search URLs (overrides the fields above) |
| `fetchDetails` | boolean | Open each listing for full text, employment type, salary and company (default true, recommended) |
| `maxResults` | integer | Maximum listings to return (1–5000, default 100) |
| `proxyConfiguration` | object | Residential DE proxy (strongly recommended — datacenter IPs are blocked) |

#### Example input

```json
{
  "keyword": "fahrer",
  "locationCode": "münchen",
  "radiusKm": 20,
  "employmentType": "Vollzeit",
  "fetchDetails": true,
  "maxResults": 100
}
```

### ⬆️ Output

Every job is one clean row (view as a **table**, or export **JSON / CSV / Excel**):

```json
{
  "ad_id": "2891234567",
  "title": "LKW Fahrer (m/w/d) in Vollzeit gesucht",
  "job_category": "Fahrer/-in",
  "employment_type": "Vollzeit",
  "salary_eur": 2800,
  "salary_period": "month",
  "experience": "Mit Berufserfahrung",
  "company": "Spedition Müller GmbH",
  "city": "München",
  "plz": "80331",
  "posted_date": "23.06.2026",
  "url": "https://www.kleinanzeigen.de/s-anzeige/...",
  "full_description": "Wir suchen ab sofort ...",
  "image_url": "https://img.kleinanzeigen.de/...",
  "scraped_at": "2026-06-24T09:00:00Z"
}
```

### 💡 Use cases

- **🧭 Recruiting & sourcing:** find local hires and employers outside the big corporate boards.
- **📊 Labour-market analysis:** track local demand, wages and employment types by region.
- **🌐 Job-board aggregation:** enrich your board with hyper-local German listings competitors miss.
- **🎯 Lead generation:** small employers actively hiring are strong, warm B2B leads.

### ❓ FAQ

**What does it scrape?** Kleinanzeigen.de (Germany), the Jobs (Stellenangebote) section — local and SME job ads from shops, restaurants, care services, trades and private employers.

**Do I need an API key?** No. There's no login or token. A residential German proxy is configured by default for reliable access, since Kleinanzeigen blocks datacenter IPs.

**Can I search by role and city?** Yes — set `keyword` (the role) and `locationCode` (PLZ or city; city names auto-resolve to the right area). Job titles reliably contain the role, so keyword filtering works well here. For full control, paste a search URL in `startUrls`.

**What fields do I get?** Title, job category, employment type (Vollzeit/Teilzeit/Minijob), salary and period (when stated), experience level, company, city, PLZ, posting date, full description and the listing URL.

**Why is the salary sometimes missing?** Many German job ads don't state pay. The Actor reads structured fields like Stundenlohn and Gehalt and falls back to parsing the description text, but when no figure is given, `salary_eur` is returned as `null`.

**Should I keep "Fetch detail pages" on?** Yes for full data — the description, employment type, salary and company live on each ad's detail page. Turning it off is faster and cheaper but returns only the basics (title, location, image).

**How is this different from an ATS or job-board scraper?** Corporate boards (Greenhouse, Lever, Ashby) only carry mid/large-company tech and office roles. Kleinanzeigen carries local, hourly, trade, care, hospitality and mini-jobs — a completely different, hyper-local inventory.

**Can I run it on a schedule or via API?** Yes — schedule recurring runs in Apify, call it via the API/SDK, or connect it to Make, Zapier or n8n.

**Is scraping Kleinanzeigen legal?** It extracts publicly available listing data. Use it responsibly and within applicable laws and Kleinanzeigen's terms.

### Support and reviews

If a successful run gives you useful job data, please leave an honest review on the [Actor review page](https://apify.com/benthepythondev/kleinanzeigen-jobs-scraper/reviews). Reviews help other buyers judge the output. For missing fields, blocked searches or failed runs, open an issue on the Actor page and include the run ID and search URL so the exact case can be reproduced.

For recurring monitoring, import the free [daily Kleinanzeigen local-job alert n8n template](https://gist.github.com/benthepythondev00/e28968a940fe4195ffb5a997fe309503#file-kleinanzeigen-local-jobs-alerts-json). It runs this Actor on a schedule and emails matching roles without embedding an Apify token in the workflow file.

### 🔗 You might also like

- **[Kleinanzeigen Scraper](https://apify.com/benthepythondev/kleinanzeigen-scraper)** — any Kleinanzeigen category, all-purpose
- **[Kleinanzeigen Immobilien Scraper](https://apify.com/benthepythondev/kleinanzeigen-immobilien-scraper)** — German real estate listings
- **[Kleinanzeigen Autos Scraper](https://apify.com/benthepythondev/kleinanzeigen-autos-scraper)** — German used-car listings

***

**Keywords:** Kleinanzeigen scraper, Kleinanzeigen Jobs, German job scraper, Stellenangebote scraper, German job listings API, local jobs Germany, job data Germany, recruiting data, labour market data, mini job scraper, DACH job data, Teilzeit Vollzeit Minijob, SME hiring leads.

# Actor input Schema

## `keyword` (type: `string`):

Filter listings whose title contains this role, e.g. 'pflegekraft', 'fahrer', 'aushilfe küche'. Leave empty to get all jobs in the location (recommended for broad local monitoring).

## `locationCode` (type: `string`):

German postal code (e.g. 10115) or city name (e.g. berlin, münchen) — city names are auto-resolved. Leave empty for all of Germany.

## `radiusKm` (type: `integer`):

Search radius around the location.

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

Paste exact kleinanzeigen.de jobs-search URLs (overrides the fields above). Most reliable for precise sub-category filters — search on kleinanzeigen.de and copy the URL.

## `employmentType` (type: `string`):

Keep only jobs whose 'Art der Anstellung' contains this text, e.g. 'Vollzeit', 'Teilzeit', 'Minijob'. Leave empty for all.

## `fetchDetails` (type: `boolean`):

Open each listing to extract the full description, employment type, salary and company (recommended).

## `maxResults` (type: `integer`):

Maximum number of listings to return. Keep small for quick scheduled/auto-test runs.

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

Residential DE proxy is strongly recommended (Kleinanzeigen blocks datacenter IPs).

## Actor input object example

```json
{
  "keyword": "",
  "locationCode": "berlin",
  "radiusKm": 0,
  "startUrls": [
    "https://www.kleinanzeigen.de/s-jobs/berlin/c102l3331"
  ],
  "employmentType": "",
  "fetchDetails": true,
  "maxResults": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}
```

# Actor output Schema

## `results` (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 = {
    "keyword": "",
    "locationCode": "berlin",
    "radiusKm": 0,
    "startUrls": [
        "https://www.kleinanzeigen.de/s-jobs/berlin/c102l3331"
    ],
    "employmentType": "",
    "fetchDetails": true,
    "maxResults": 3,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "DE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("benthepythondev/kleinanzeigen-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 = {
    "keyword": "",
    "locationCode": "berlin",
    "radiusKm": 0,
    "startUrls": ["https://www.kleinanzeigen.de/s-jobs/berlin/c102l3331"],
    "employmentType": "",
    "fetchDetails": True,
    "maxResults": 3,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "DE",
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "keyword": "",
  "locationCode": "berlin",
  "radiusKm": 0,
  "startUrls": [
    "https://www.kleinanzeigen.de/s-jobs/berlin/c102l3331"
  ],
  "employmentType": "",
  "fetchDetails": true,
  "maxResults": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}' |
apify call benthepythondev/kleinanzeigen-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=benthepythondev/kleinanzeigen-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/171kI4RBHtaDNb4xI/builds/Y5yOWLeluTN2Smggw/openapi.json
