# Jobmittelland Jobs Search Scraper (`alexist/jobmittelland-jobs-search-scraper`) Actor

Scrape job search results from Jobmittelland.ch, Switzerland's premier employment platform for the Midland region. Collect job titles, company details, salaries, location data, and 27+ fields per listing — perfect for recruiters, HR professionals, and labor market researchers.

- **URL**: https://apify.com/alexist/jobmittelland-jobs-search-scraper.md
- **Developed by:** [Alex](https://apify.com/alexist) (community)
- **Categories:** Automation, Developer tools, Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

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

## Jobmittelland.ch Jobs Search Scraper: Extract Swiss Midland Job Listings

***

### What Is Jobmittelland.ch?

Jobmittelland.ch is a leading Swiss job board specializing in employment opportunities across the Midland cantons (Bern, Lucerne, Solothurn, and surrounding regions). It hosts thousands of active job postings across industries, from entry-level roles to senior positions. The platform serves both employers posting vacancies and job seekers searching by location, sector, and salary. Manually collecting and organizing this data is labor-intensive — the **Jobmittelland Jobs Search Scraper** automates extraction, delivering clean, structured records ready for analysis and integration.

***

### Overview

The **Jobmittelland Jobs Search Scraper** extracts job listings from search result pages on Jobmittelland.ch, converting unstructured web data into machine-readable records. It is designed for:

- **Recruiters & staffing agencies** monitoring market activity and competitor postings
- **HR professionals** benchmarking salaries and job requirements across the region
- **Labor market researchers** analyzing employment trends in Switzerland
- **Job aggregator platforms** feeding data into custom boards or dashboards
- **Business intelligence teams** tracking hiring patterns by canton and industry

Key strengths include configurable item limits, URL-based filtering for targeted collection, and resilient error handling to ensure continuous runs even when some pages fail.

***

### Input Format

The scraper accepts a JSON configuration object with flexible parameters:

```json
{
  "urls": [
    "https://www.jobmittelland.ch/job/alle-jobs-seite-2"
  ],
  "max_items_per_url": 200,
  "ignore_url_failures": true
}
```

| Parameter | Type | Description |
|---|---|---|
| `urls` | Array | List of Jobmittelland job search result page URLs (e.g., search results filtered by canton, keyword, or salary range) |
| `max_items_per_url` | Integer | Maximum listings to extract per URL (default: 100, max: 200) |
| `ignore_url_failures` | Boolean | If `true`, skips URLs that fail to load instead of stopping the run. Recommended for bulk operations |

**Examples of valid URLs:**

- Search results by canton: `https://www.jobmittelland.ch/job/bern`
- Paginated results: `https://www.jobmittelland.ch/job/alle-jobs-seite-2`
- Filtered searches: `https://www.jobmittelland.ch/job/search?canton=lucerne&sector=healthcare`

> **Tip:** Use paginated URLs or canton-specific searches to maximize the value of each run.

***

### Output Format

**Sample output**

```json
{
  "id": 330152,
  "title": "Bäcker:in - Konditor:in",
  "company_id": 28172,
  "workplace_zip": "4562",
  "workplace_city": "Biberist",
  "activity": "Arbeiten, wo die Schweiz einkauft Bei Coop kauft die Schweiz ein! Wir sind stolz darauf, unsere Kundschaft willkommen zu heissen und ihr Einkaufserlebnis mitzugestalten. Als Teil unseres Teams hilfst du genau dabei. Lass uns gemeinsam dafür sorgen, dass unsere Kundschaft immer wieder gerne zu uns kommt und sei Teil des Schweizer Einkaufserlebnisses. Pensum 40 - 100% Vertrag unbefristet Stellenantritt per sofort oder nach Vereinbarung Aufgaben  ... ",
  "requirements": "",
  "offer": "",
  "contact": "<b>Germann Steiner</b><br />HR Marketing",
  "url_application": "https://ohws.prospective.ch/public/v1/redirect/4a4eadb1-232a-47d2-a825-1ec4d5a25fd6/ats",
  "is_shown_on_company_minisite": false,
  "date_first_published": "2026-07-18T04:10:59.034+02:00",
  "date_start": "2026-07-18",
  "date_end": null,
  "company_description": "",
  "keywords": "Bäckerei, Konditorei, Verkauf, Food, Kundschaft, Backwaren",
  "type_key": 5,
  "type_value_min": 40,
  "type_value_max": 100,
  "date_actualization": "2026-07-18",
  "is_special_offer": false,
  "is_promoted": false,
  "position": [],
  "external_id": "10117913",
  "home_office": false,
  "country_code": [
    "ch"
  ],
  "video_url": null,
  "coordinates": [
    {
      "ort": "Biberist",
      "latitude": 47.185965,
      "longitude": 7.546215
    }
  ],
  "cantons": [
    "Solothurn"
  ],
  "updated_at": "2026-07-18T10:10:57.678+02:00",
  "company": {
    "id": 28172,
    "name": "Coop",
    "description": "<strong><span style=\"font-size:18px;\">Jobs und Karriere bei Coop</span></strong><br />\n<br />\nDetailhandel, Grosshandel und Produktion – mit vielfältigen Jobs in unserer Coop-Welt bieten wir Ihnen spannende Berufs- und Karrieremöglichkeiten. Mit über 90'000 Mitarbeitenden aus 120 Nationen, verteilt auf 22 Länder gehen wir gemeinsam an die Spitze.",
    "homepage": "https://www.coopjobs.ch/de.html",
    "additional_address": "",
    "vacancy_list_style_class": "Ostjob_Vacancy_ListStyle_Default",
    "zip": "4002",
    "city": "Basel",
    "hide_first_publication_date": false,
    "street": "Thiersteinerallee",
    "house_number": "14",
    "po_box": "",
    "country": "Schweiz",
    "additional_name": "Personal Hauptsitz",
    "main_phone_number": "+41 61 336 66 66",
    "pdf_preview_enable": true,
    "contact_and_application_url_enable": true,
    "vacancies_in_popup": false,
    "is_shown_iframe_on_mobile_pages": true,
    "show_template_on_mobile": false,
    "logo_id": "98cdbecd4bdaa371476b",
    "country_of_origin_code": "ch",
    "is_free_company": false,
    "with_profile": true,
    "profile": {
      "company_id": 28172,
      "social_urls": [
        {
          "name": "facebook",
          "url": "https://www.facebook.com/coop.ch"
        },
        {
          "name": "twitter",
          "url": "https://twitter.com/coop_ch"
        },
        {
          "name": "instagram",
          "url": "https://www.instagram.com/coop.ch/"
        },
        {
          "name": "youtube",
          "url": "https://www.youtube.com/coopschweiz"
        },
        {
          "name": "xing",
          "url": "https://www.xing.com/pages/coop"
        },
        {
          "name": "kununu",
          "url": "https://www.kununu.com/ch/coop"
        },
        {
          "name": "linkedin",
          "url": "https://www.linkedin.com/company/coop_2/"
        }
      ],
      "company_site": "https://www.coopjobs.ch/de.html ",
      "career_site": "https://www.coopjobs.ch/de.html",
      "contact": {
        "firstname": "Employer Branding",
        "email": "employerbranding@coop.ch"
      },
      "active_sections": [
        "jobs",
        "about_us",
        "photo_video",
        "benefits",
        "career"
      ]
    }
  },
  "from_url": "https://www.jobmittelland.ch/job/alle-jobs"
}
```

Each scraped job returns a comprehensive record with 27 fields across multiple categories:

#### Core Identification

| Field | Meaning |
|---|---|
| `id` | Unique job ID in the Jobmittelland database |
| `external_id` | External identifier (if linked from another system) |
| `title` | Job title as displayed in the listing |
| `url_application` | Direct link to apply or access full job details |

#### Company Information

| Field | Meaning |
|---|---|
| `company` | Employer name and details |
| `company_id` | Unique company identifier |
| `company_description` | Description of the employer and organization |
| `is_shown_on_company_minisite` | Boolean flag: whether featured on the company's profile page |

#### Location & Geography

| Field | Meaning |
|---|---|
| `workplace_city` | City where the job is located |
| `workplace_zip` | Postal code of the job location |
| `cantons` | Swiss cantons associated with the role (e.g., Bern, Lucerne) |
| `country_code` | ISO country code (typically `CH` for Switzerland) |
| `coordinates` | GPS coordinates (latitude, longitude) of the job location |
| `home_office` | Percentage or description of remote work flexibility |

#### Job Details & Requirements

| Field | Meaning |
|---|---|
| `activity` | Sector or industry category (e.g., healthcare, IT, retail) |
| `requirements` | Candidate skills, qualifications, and experience needed |
| `keywords` | SEO and searchable tags associated with the role |
| `type_key` | Employment type category (e.g., full-time, part-time, temporary) |
| `type_value_min` | Minimum value for the employment type (e.g., min. hours/week) |
| `type_value_max` | Maximum value (e.g., max. hours/week or contract length) |

#### Compensation & Offer

| Field | Meaning |
|---|---|
| `offer` | Job description, responsibilities, and benefits offered |
| `contact` | Contact information for inquiries or applications |
| `position` | Seniority level or position category within the organization |

#### Dates & Status

| Field | Meaning |
|---|---|
| `date_first_published` | When the listing was first posted on Jobmittelland |
| `date_start` | Earliest start date for the position |
| `date_end` | Application deadline or listing expiry date |
| `date_actualization` | Last update timestamp for the listing |
| `updated_at` | Most recent modification time |

#### Marketing & Visibility

| Field | Meaning |
|---|---|
| `is_promoted` | Boolean: whether the listing has paid promotion |
| `is_special_offer` | Boolean: whether marked as a featured or special opportunity |
| `video_url` | Link to a video presentation (if available) |

***

### How to Use

1. **Identify target URLs** — Navigate to Jobmittelland.ch and build search URLs matching your criteria (e.g., by canton, keyword, salary range, or industry).
2. **Configure the scraper** — Paste URLs into the `urls` array and set `max_items_per_url` (recommend 100–200 for comprehensive results).
3. **Enable resilience** — Set `ignore_url_failures: true` to ensure long runs complete even if a page temporarily fails.
4. **Run the scraper** — Start the actor and monitor progress in the logs.
5. **Export results** — Download data as JSON or CSV for use in spreadsheets, databases, or analytics tools.

**Best practices:**

- Use canton-specific URLs for regional analysis (e.g., `/job/bern`, `/job/lucerne`).
- Combine multiple search filters in a single run to reduce API calls.
- Set `max_items_per_url` to 200 for paginated results to capture all listings.

***

### Use Cases & Business Value

- **Talent acquisition:** Build candidate pipelines by monitoring job openings in your industry and region
- **Salary benchmarking:** Analyze compensation trends across cantons and sectors
- **Competitor intelligence:** Track hiring activity and positioning of rival companies
- **Labor market analytics:** Identify skill gaps and employment hotspots in the Midland region
- **Job aggregation:** Feed data into internal job boards, intranet portals, or public aggregator sites

The Jobmittelland Jobs Search Scraper transforms raw web data into actionable intelligence, enabling data-driven recruitment strategy and market insights.

***

### Conclusion

The **Jobmittelland.ch Jobs Search Scraper** is an efficient, reliable solution for extracting structured job data from Switzerland's Midland job market. With 27 detailed output fields, flexible URL filtering, and resilient error handling, it empowers recruiters, researchers, and HR teams to make informed decisions faster. Start scraping today and unlock the full potential of Jobmittelland's job listings.

# Actor input Schema

## `urls` (type: `array`):

Add the URLs of the Jobs list urls you want to scrape. You can paste URLs one by one, or use the Bulk edit section to add a prepared list.

## `ignore_url_failures` (type: `boolean`):

If true, the scraper will continue running even if some URLs fail to be scraped.

## `max_items_per_url` (type: `integer`):

The maximum number of items to scrape per URL.

## Actor input object example

```json
{
  "urls": [
    "https://www.jobmittelland.ch/job/alle-jobs-seite-2"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 100
}
```

# 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 = {
    "urls": [
        "https://www.jobmittelland.ch/job/alle-jobs-seite-2"
    ],
    "ignore_url_failures": true,
    "max_items_per_url": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("alexist/jobmittelland-jobs-search-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 = {
    "urls": ["https://www.jobmittelland.ch/job/alle-jobs-seite-2"],
    "ignore_url_failures": True,
    "max_items_per_url": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("alexist/jobmittelland-jobs-search-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 '{
  "urls": [
    "https://www.jobmittelland.ch/job/alle-jobs-seite-2"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 100
}' |
apify call alexist/jobmittelland-jobs-search-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/NSl6kZRY3pbIRa0qa/builds/aWJKayNezqsD34aHH/openapi.json
