# Jobsite Scraper (`maximedupre/jobsite-scraper`) Actor

Scrape Jobsite jobs by keyword, location, filters, or pasted URLs. Get full descriptions, salaries, employers, locations, apply links, listing metadata, contact hints, and scrape metadata in clean dataset items.

- **URL**: https://apify.com/maximedupre/jobsite-scraper.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.01 / 1,000 scraped 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/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

### 🔎 Jobsite jobs scraper for UK job listings

Jobsite Scraper collects public UK job listings from [Jobsite](https://www.jobsite.co.uk/) and saves them as clean Apify dataset rows. Use it to build Jobsite searches from keywords and locations, reuse Jobsite search URLs, or save direct job pages with titles, employers, salaries, descriptions, apply links, listing context, and source ranks.

- [Track Jobsite UK jobs](https://apify.com/maximedupre/jobsite-scraper/examples/track-jobsite-uk-jobs) by role, location, salary band, employer, or posting date.
- [Build repeatable job exports](https://apify.com/maximedupre/jobsite-scraper/examples/build-repeatable-job-exports) for recruiting research, labour-market monitoring, or hiring dashboards.
- [Collect full job descriptions and apply metadata](https://apify.com/maximedupre/jobsite-scraper/examples/collect-full-job-descriptions) from Jobsite pages when the source shows them.
- [Compare salary ranges, workplace signals, employers, and apply flows](https://apify.com/maximedupre/jobsite-scraper/examples/compare-jobsite-salary-ranges) across Jobsite search results.
- [Save direct Jobsite job pages](https://apify.com/maximedupre/jobsite-scraper/examples/save-direct-jobsite-job-pages) into one consistent dataset for review, QA, or downstream systems.

#### 📦 Jobsite job data you can export

Each dataset item is one accepted Jobsite job. Fields can be empty when Jobsite does not show that value for a posting.

| Data group | Fields |
| --- | --- |
| Job identity | `jobId`, `harmonisedId`, `jobUrl`, `title` |
| Dates and detail state | `datePosted`, `validThrough`, `detailStatus` |
| Employer | `employer.id`, `employer.name`, `employer.url`, `employer.logoUrl` |
| Location | `location.locality`, `location.region`, `location.postalCode`, `location.country`, `location.latitude`, `location.longitude` |
| Salary | `salary.raw`, `salary.min`, `salary.max`, `salary.currency`, `salary.period` |
| Apply flow | `apply.url`, `apply.type`, `apply.isDirect` |
| Listing context | `listing.skills`, `listing.snippet`, `listing.workFromHome`, `listing.crossPostedCount`, `listing.isSponsored`, `listing.isHighlighted`, `listing.isTopJob`, `listing.sourceSiteName` |
| Full details | `details.descriptionHtml`, `details.descriptionText`, `details.employmentType`, `details.industry`, `details.jobLocationType`, `details.applicantLocationRequirements`, `details.companyProfile` |
| Contact hints | `contacts.emails`, `contacts.phones`, `contacts.evidence` |
| Source context | `source.searchUrl`, `source.keyword`, `source.location`, `source.page`, `source.rank` |

The Actor keeps missing source data empty instead of inventing salaries, coordinates, contacts, employment types, or apply destinations.

#### 🚀 How to run it

For a small first run:

1. Enter a role or skill in `Keywords`, such as `software engineer`.
2. Add one or more UK locations in `Locations`, such as `London`.
3. Keep `Radius` at `10` miles, or set it to `0` for the exact location search.
4. Keep `Maximum jobs` at `100` for a useful first export, or lower it for a smaller test.
5. Keep `Detail mode` set to `Full details`.
6. Run the Actor and open the dataset.

You can also add public Jobsite search pages or direct job pages in `Jobsite URLs`. When URLs are present, the Actor uses those URLs as the target for the run.

#### 🎛️ Input options

- `Keywords`: role, skill, company, or hiring terms for built searches.
- `Locations`: UK towns, cities, regions, or postcodes for built searches.
- `Radius`: search radius around each location, in miles.
- `Job type`: filter by any, permanent, contract, temporary, part-time, or work-from-home jobs.
- `Advertiser`: filter by direct employer or recruitment agency.
- `Minimum salary` and `Salary period`: request a salary filter from Jobsite.
- `Posted within`: request jobs posted in the last 24 hours, 3 days, 7 days, or 14 days.
- `Sort by`: request relevance, newest, salary, or distance ordering.
- `Jobsite URLs`: paste public Jobsite search pages or direct job pages.
- `Detail mode`: use `Full details` for job pages and descriptions, or `Fast listings` for listing-page fields.
- `Include contact hints`: collect visible public emails and phone numbers from job text when present.
- `Maximum jobs`: total jobs to save across the run.
- `Maximum pages per search`: result pages to read for built searches and pasted search URLs.

You do not need Jobsite cookies, a Jobsite account, or a separate Jobsite API key.

#### 🧾 Output example

```json
{
  "jobId": "107494478",
  "harmonisedId": "7bb8a2b0-4b5d-4b29-9b5f-6e2f8b7b4e20",
  "jobUrl": "https://www.jobsite.co.uk/job/software-engineer/example-employer-job107494478",
  "title": "Software Engineer",
  "datePosted": "2026-06-09",
  "validThrough": "2026-07-09",
  "detailStatus": "full",
  "employer": {
    "id": "123456",
    "name": "Example Employer",
    "url": "https://www.jobsite.co.uk/jobs/example-employer",
    "logoUrl": "https://www.jobsite.co.uk/company-logo.png"
  },
  "location": {
    "locality": "London",
    "region": null,
    "postalCode": null,
    "country": "GB",
    "latitude": 51.5072,
    "longitude": -0.1276
  },
  "salary": {
    "raw": "£55,000 - £70,000",
    "min": 55000,
    "max": 70000,
    "currency": "GBP",
    "period": "year"
  },
  "apply": {
    "url": "https://www.jobsite.co.uk/apply/107494478",
    "type": "direct",
    "isDirect": true
  },
  "listing": {
    "skills": ["TypeScript", "AWS"],
    "snippet": "Build and maintain customer-facing services.",
    "workFromHome": "Hybrid",
    "crossPostedCount": 1,
    "isSponsored": false,
    "isHighlighted": false,
    "isTopJob": false,
    "sourceSiteName": "Jobsite"
  },
  "details": {
    "descriptionHtml": "<p>Full public job description text...</p>",
    "descriptionText": "Full public job description text...",
    "employmentType": "FULL_TIME",
    "industry": "Technology",
    "jobLocationType": null,
    "applicantLocationRequirements": null,
    "companyProfile": null
  },
  "contacts": {
    "emails": [],
    "phones": [],
    "evidence": []
  },
  "source": {
    "searchUrl": "https://www.jobsite.co.uk/jobs/software-engineer/in-london/?radius=10",
    "keyword": "software engineer",
    "location": "London",
    "page": 1,
    "rank": 1
  }
}
```

#### 💳 Pricing

This Actor uses pay-per-event pricing. You are charged `$0.00001` for each job saved to the dataset, which is `$0.01 per 1,000 saved jobs`. Runs that find no matching jobs do not create paid job items.

#### 🔌 Integrations

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

- Export Jobsite jobs as JSON, CSV, Excel, XML, RSS, or HTML from the Apify dataset.
- Run the scraper through the Apify API for repeat job-data pipelines.
- Schedule searches to monitor new Jobsite results for roles, locations, employers, or salary bands.
- Send finished runs to webhooks, CRMs, spreadsheets, warehouses, or alerting tools.

#### ❓ FAQ

##### Can I scrape Jobsite without a login?

Yes. This Actor works with public Jobsite pages and does not ask for Jobsite cookies, passwords, or API keys.

##### Can I paste Jobsite URLs?

Yes. Add public Jobsite search pages or direct job pages in `Jobsite URLs`. Direct job pages normally save one job each.

##### What does full details mode add?

`Full details` visits each job page and saves richer fields when Jobsite shows them, such as full descriptions, apply metadata, employment type, valid-through dates, coordinates, and visible contact hints.

##### When should I use fast listings mode?

Use `Fast listings` when you want a quicker overview from listing pages and do not need full descriptions or detail-page fields for every job.

##### Why is a salary field empty?

Some Jobsite postings do not show salary details. When salary text is visible, the Actor saves the raw text and tries to normalize numeric min and max values.

##### Are contact hints guaranteed?

No. Contact hints are saved only when public job text or links visibly include an email address or phone number.

##### What happens when Jobsite does not return a page?

The Actor handles skipped, removed, unsupported, and degraded pages without saving placeholder rows. If a run finds no matching jobs, it completes with no paid job items.

##### Why not use the Jobsite API?

Jobsite does not provide a public self-serve API for this dataset in the Actor input. This Actor collects public Jobsite pages and returns structured rows you can use through Apify exports, API, schedules, and integrations.

##### What are Jobsite alternatives?

For UK job data, related sources include CWjobs, Goodmoves, Welcome to the Jungle, Reed, LinkedIn Jobs, and other job boards. Use this Actor when you specifically need public Jobsite listings and Jobsite URLs.

### 📝 Changelog

- 0.2: Added radius search, cleaner target selection, richer source context, full-detail output groups, and floor pricing for saved Jobsite jobs.
- 0.1: Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~jobsite-scraper/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Other actors

- [CWjobs Scraper ↗](https://apify.com/maximedupre/cwjobs-scraper) - Scrape UK tech job listings with employers, salaries, descriptions, and source links.
- [Goodmoves Jobs Scraper ↗](https://apify.com/maximedupre/goodmoves-jobs-scraper) - Collect Scottish charity and social-impact jobs with organisation and salary fields.
- [Welcome to the Jungle Jobs Scraper ↗](https://apify.com/maximedupre/welcometothejungle-jobs-extractor) - Extract public WTTJ jobs with company, salary, location, and description data.
- [CutShort Scraper ↗](https://apify.com/maximedupre/cutshort-scraper) - Scrape public CutShort tech and startup jobs with salary, skills, and recruiter fields.
- [LinkedIn Company Scraper ↗](https://apify.com/maximedupre/linkedin-company-scraper) - Enrich hiring research with public LinkedIn company profile data.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `keywords` (type: `string`):

Role, skill, company, or hiring terms for built searches.

## `locations` (type: `array`):

UK towns, cities, regions, or postcodes for built searches.

## `radiusMiles` (type: `integer`):

Search radius around each location, in miles.

## `jobType` (type: `string`):

Filter built searches by Jobsite job type.

## `advertiserType` (type: `string`):

Filter built searches by direct employer or agency.

## `minSalary` (type: `integer`):

Minimum advertised salary for built searches.

## `salaryPeriod` (type: `string`):

Salary period for the minimum salary filter.

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

Posted date window for built searches.

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

Result order for built searches.

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

Public Jobsite search pages or direct job pages.

## `detailMode` (type: `string`):

Full details fetches each job page. Fast listings saves listing-page fields.

## `includeContactHints` (type: `boolean`):

Add visible company and recruiter contact hints.

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

Total jobs to save across the whole run.

## `maxPagesPerSearch` (type: `integer`):

Result pages to read for built searches and pasted search URLs.

## Actor input object example

```json
{
  "keywords": "software engineer",
  "locations": [
    "London"
  ],
  "radiusMiles": 10,
  "jobType": "any",
  "advertiserType": "any",
  "salaryPeriod": "annual",
  "postedWithinDays": "7",
  "sortBy": "relevance",
  "detailMode": "fullDetails",
  "includeContactHints": true,
  "maxItems": 100,
  "maxPagesPerSearch": 4
}
```

# Actor output Schema

## `results` (type: `string`):

Open the dataset with job titles, employers, salaries, locations, apply links, details, contact hints, and source context.

# 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 = {
    "keywords": "software engineer",
    "locations": [
        "London"
    ],
    "radiusMiles": 10,
    "postedWithinDays": "7",
    "maxItems": 100,
    "maxPagesPerSearch": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/jobsite-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 = {
    "keywords": "software engineer",
    "locations": ["London"],
    "radiusMiles": 10,
    "postedWithinDays": "7",
    "maxItems": 100,
    "maxPagesPerSearch": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/jobsite-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 '{
  "keywords": "software engineer",
  "locations": [
    "London"
  ],
  "radiusMiles": 10,
  "postedWithinDays": "7",
  "maxItems": 100,
  "maxPagesPerSearch": 4
}' |
apify call maximedupre/jobsite-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/jobsite-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/ema8d15E5ZOMVdpEr/builds/XCKZ33M7tqyITZYzP/openapi.json
