# Robert Half Scraper — Multi-Country Staffing Agency Jobs (`studio-amba/roberthalf-scraper`) Actor

Scrape job listings from Robert Half across the UK, Germany, France, the Netherlands, Belgium and Switzerland — a leading specialized staffing agency. No login or cookies required.

- **URL**: https://apify.com/studio-amba/roberthalf-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Robert Half Scraper — Multi-Country

Extract job listings from [Robert Half](https://www.roberthalf.com), a leading specialized staffing agency for finance, accounting, technology, legal, admin and HR roles, as clean structured JSON — across six European markets from a single actor. Pick a country, search by keyword, and get job titles, locations, salary, worksite, employment type and full descriptions.

No login. No cookies. No browser automation. Robert Half's job listing pages are fully server-rendered, so this actor reads the same HTML a browser would — no hidden API to reverse-engineer, no JavaScript execution needed.

### What this actor does

Robert Half runs one global platform at `roberthalf.com` with a locale path per market (`gb/en`, `de/de`, `fr/fr`, `nl/nl`, `be/en`, `be/fr`, `be/nl`, `ch/de`, `ch/fr`, `ch/en`). This actor requests your chosen country's job search page directly and returns one row per job with:

- Job title
- Location (as posted)
- Worksite (remote / hybrid / onsite, where disclosed)
- Employment type (Permanent, Contract, etc.)
- Salary — min, max, currency and period, when disclosed
- A 300–400 character description excerpt (already present on the listing page — no separate detail-page request needed)
- Robert Half's own job detail page URL

### Supported countries

| Input value | Market |
|---|---|
| `GB` | United Kingdom — default |
| `DE` | Germany |
| `FR` | France |
| `NL` | Netherlands |
| `BE-en` | Belgium (English) |
| `BE-fr` | Belgium (French) |
| `BE-nl` | Belgium (Dutch) |
| `CH-de` | Switzerland (German) |
| `CH-fr` | Switzerland (French) |
| `CH-en` | Switzerland (English) |

Ireland was checked and excluded: `roberthalf.com/ie/en` is a stub market page (salary guide and insights content only) with no job listings section — confirmed via the sitemap and by testing every plausible jobs-page URL. All ten market/language combinations above were verified live against real, current listings before shipping.

### Why use it

- **Pan-European staffing market research** — track what roles Robert Half is placing across six countries from one tool instead of six.
- **Recruitment and sourcing** — build a live feed of contract and permanent finance, tech, legal and admin positions for a role or region.
- **Salary benchmarking** — a large share of listings disclose a salary range, currency and pay period.
- **Competitive intelligence for staffing/recruitment businesses** — see what a top-tier competitor is hiring for, where, and at what pay.

### How to scrape Robert Half data

1. Open the actor and pick a **Country** (e.g. `DE` for Germany).
2. Set a **Search Query** in the local language (e.g. `accountant` for the UK, `buchhalter` for Germany or German-speaking Switzerland, `comptable` for France or French-speaking Switzerland, `boekhouder` for Belgium-Dutch). Leave it empty to get the most recent listings for the whole country.
3. Optionally set a **Location filter** (e.g. `london`, `berlin`) — Robert Half's own search applies this server-side.
4. Set **Max Results** — the actor pages through the site's search results at 25 per page until it reaches this number or runs out of listings.
5. Leave the proxy on the default automatic setting and click **Start**.

The actor requests each page of results directly from `roberthalf.com`, parses the job cards already present in the HTML (title, location, worksite, employment type, salary, full description), and writes everything to the dataset — no per-job detail requests required.

### Input

| Field | Type | Description |
|-------|------|-------------|
| `country` | string | Market to search. One of `GB`, `DE`, `FR`, `NL`, `BE-en`, `BE-fr`, `BE-nl`, `CH-de`, `CH-fr`, `CH-en`. Default: `GB`. |
| `searchQuery` | string | Keyword in the local language. Empty = all current listings, most recent first. |
| `location` | string | Optional city/region filter, applied server-side by Robert Half's own search. |
| `maxResults` | integer | Maximum number of listings to return (max 500). Default: `50`. |
| `proxyConfiguration` | object | Apify proxy settings. Default: automatic (no residential proxy needed). |

#### Example input

```json
{
    "country": "DE",
    "searchQuery": "buchhaltung",
    "location": "",
    "maxResults": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
}
```

### Output

Each dataset item looks like this:

```json
{
    "title": "Management Accountant",
    "company": "Robert Half",
    "locationRaw": "Bristol, Bristol",
    "locationParsed": { "country": "United Kingdom" },
    "language": "en",
    "worksite": "remote",
    "employmentType": "Permanent",
    "salaryRaw": "50000-60000 GBP / Yearly",
    "salaryMin": 50000,
    "salaryMax": 60000,
    "salaryCurrency": "GBP",
    "salaryPeriod": "Yearly",
    "descriptionSnippet": "Management Accountant | £50,000 - £60,000 | Bristol | On site | Full Time Robert Half is delighted to be supporting Seabank Power Limited in the search for a qualified Management Accountant...",
    "url": "https://www.roberthalf.com/gb/en/job/bristol-bristol/management-accountant/06010-0013476048-uken",
    "source": "roberthalf.com/gb/en",
    "scrapedAt": "2026-09-04T09:12:30.268Z",
    "jobId": "06010-0013476048-uken"
}
```

#### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `title` | string | Job title, as posted |
| `company` | string | Always `Robert Half` |
| `locationRaw` | string | Location as shown on the listing |
| `locationParsed` | object | `{ country }` |
| `language` | string | ISO 639-1 language code of the site the listing was scraped from |
| `worksite` | string | Work arrangement — `remote`, `hybrid`, `onsite`, when disclosed |
| `employmentType` | string | Contract type, e.g. `Permanent`, `Contract` |
| `salaryRaw` | string | Raw salary range with currency and period, when disclosed |
| `salaryMin` / `salaryMax` | integer | Parsed salary bounds, when disclosed |
| `salaryCurrency` | string | Currency code, e.g. `GBP`, `EUR` |
| `salaryPeriod` | string | Salary period, e.g. `Yearly`, `Daily` |
| `descriptionSnippet` | string | 300–400 character plain-text excerpt |
| `url` | string | Robert Half's own job detail page URL |
| `source` | string | Source identifier, e.g. `roberthalf.com/gb/en` |
| `scrapedAt` | string | ISO 8601 timestamp of collection |
| `jobId` | string | Unique Robert Half job identifier |

### Cost estimate

Each run makes one HTML request per 25 results — no browser, no per-job detail requests (the full description is already on the listing page). A 50-result run is 2 requests total plus proxy traffic. Usage is only charged after a run finishes with status SUCCEEDED — a failed or aborted run doesn't bill for partial results.

### Limitations

- **Ireland is not covered.** `roberthalf.com/ie/en` has no job listings section — verified live, it only serves salary guide and insights content.
- **Belgium's three language variants share the same job pool.** `BE-en`, `BE-fr` and `BE-nl` return the same underlying listings, rendered and searched in a different site language each — keep this in mind if you're running all three to avoid counting the same jobs twice.
- **Salary is often undisclosed.** A meaningful share of listings show "Competitive" rather than a number — `salaryMin`/`salaryMax` are left empty rather than coerced to zero.
- **Fixed page size of 25.** Verified live — no page-size override parameter was found.

### Related scrapers

Building a European staffing dataset? These sibling actors follow the same clean, server-rendered-HTML approach:

- **Adecco Scraper** — pan-European staffing agency, Belgium/Netherlands/France/Spain/Italy/Poland
- **Randstad Belgium Scraper** — the world's largest staffing agency, Belgian market
- **Manpower Scraper** — pan-European staffing agency, Germany/Belgium/Netherlands
- **VDAB Scraper** — Flemish public employment service
- **StepStone Scraper** — Belgian commercial job board

### Disclaimer

This actor collects publicly available data from Robert Half for legitimate research and aggregation use. Respect Robert Half's terms of service and applicable data protection law when using the output.

# Actor input Schema

## `country` (type: `string`):

Robert Half market to search. Belgium and Switzerland have separate listings per site language.

## `searchQuery` (type: `string`):

Keyword to search for, in the local language (e.g. 'accountant' for UK, 'buchhalter' for Germany/Swiss-German, 'comptable' for France/Swiss-French, 'accountant' for Netherlands/Belgium-EN, 'boekhouder' for Belgium-Dutch). Leave empty to return all current listings for the selected country, sorted by most recently posted.

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

Optional city or region to filter results by, e.g. 'london' or 'berlin'. Applied server-side by Robert Half's own search — leave empty to search nationwide.

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

Maximum number of job listings to return. Robert Half's listing pages return 25 results per page — larger values page through more results.

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

Proxy settings. Robert Half's job pages are server-rendered and did not require a residential proxy during testing — Apify's automatic proxy is sufficient.

## Actor input object example

```json
{
  "country": "GB",
  "searchQuery": "accountant",
  "maxResults": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "searchQuery": "accountant",
    "maxResults": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/roberthalf-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 = {
    "searchQuery": "accountant",
    "maxResults": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/roberthalf-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 '{
  "searchQuery": "accountant",
  "maxResults": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call studio-amba/roberthalf-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/roberthalf-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/xYnigFp8qx93t0C3f/builds/2zyyFU0RoW7xB5jd1/openapi.json
