# SEEK Jobs Scraper (`neuro-scraper/seek-jobs-scraper`) Actor

SEEK Jobs Scraper SD - SEEK Jobs Scraper is a job data tool that extracts job listings from SEEK, Jobstreet and JobsDB in 8 countries: title, company, location, salary, work type, classification, listing date and full description. No login.

- **URL**: https://apify.com/neuro-scraper/seek-jobs-scraper.md
- **Developed by:** [Neuro Scraper](https://apify.com/neuro-scraper) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

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

### SEEK Jobs Scraper — SEEK, Jobstreet and JobsDB job listings

The SEEK Jobs Scraper searches the SEEK job platform in 8 countries and returns one row per job: title, company, location, salary text, work type, work arrangement, classification, listing and expiry dates, teaser, bullet points and the full description.

| Site | Countries |
|---|---|
| SEEK | Australia, New Zealand |
| Jobstreet | Malaysia, Singapore, Philippines, Indonesia |
| JobsDB | Hong Kong, Thailand |

It reads the public JSON the sites' own search uses. No login, no key, no cookie.

#### Input

| Field | Type | Default | Meaning |
|---|---|---|---|
| `keywords` | list | `python developer` (prefill) | One search per line |
| `site` | select | `AU` | AU, NZ, MY, SG, PH, ID, HK, TH |
| `location` | text | `All Sydney NSW` (prefill) | As typed on the site; empty = whole country |
| `startUrls` | URLs | – | SEEK / Jobstreet / JobsDB search URLs; their filters (`daterange`, `worktype`, `classification`, `salaryrange`, `sortmode` ...) are kept |
| `dateRange` | integer | `0` | Only jobs listed in the last N days |
| `sortBy` | select | `relevance` | Relevance or newest first (the sort value is read from the site's answer) |
| `scrapeDetails` | boolean | `true` | One extra request per job for the full description and expiry date |
| `maxItems` | integer | `50` | Stop after this many jobs |
| `proxyConfiguration` | proxy | Apify RESIDENTIAL | Proxy |

#### Output

| Field | Meaning |
|---|---|
| `jobId`, `jobUrl`, `title` | Job and its page (`https://<site>/job/<id>`) |
| `companyName`, `advertiserId`, `logoUrl` | Advertiser |
| `location`, `locations`, `countryCode` | Location labels |
| `classification`, `subClassification` | e.g. "Information & Communication Technology" / "Engineering - Software" |
| `workTypes`, `workArrangement`, `salary` | "Full time", "Hybrid", salary text as the advertiser wrote it |
| `teaser`, `bulletPoints`, `isFeatured` | List fields |
| `listedAt`, `listedAgo`, `expiresAt` | Dates (`expiresAt` with details) |
| `descriptionText`, `descriptionHtml` | Full description (with details) |
| `site`, `searchKeywords`, `searchLocation`, `searchUrl`, `scrapedAt` | `searchUrl` is the public search-API request that produced the row |

#### Measured (2026-10-03, one residential IP, no proxy)

| Test | Result |
|---|---|
| SEEK AU `python developer` / All Sydney NSW, 50 with descriptions | 50 rows in 63 s (2 search pages + 50 detail calls, all HTTP 200) |
| Jobstreet MY `python`, newest first, 100, no details | 100 rows in 8 s from 4 pages |
| SEEK URL nurse / Melbourne, `daterange=7&worktype=242` | 20 rows: 20/20 Full time, all listed in the last 7 days |
| JobsDB HK search URL / Jobstreet PH keyword, with descriptions | 8 rows in 13 s / 5 rows in 8 s; descriptions 8/8 and 5/5 |
| Site `US`, non-SEEK URL, empty input | Clean stop with an error line |

#### Limits (measured)

- SEEK Australia stops a search after about 500 results (page size 100: page 5 full, page 6 empty, with 714 reported); split by location, classification or date. Jobstreet Malaysia returned every page to the end in the ALGORITHMS research.
- The sites' HTML pages answer a Cloudflare challenge to non-browser clients, so only their JSON search and GraphQL job details are used.
- `salary` is the advertiser's own text and is empty when hidden (22 of 50 had one in the AU test).

#### Example input

```json
{"keywords": ["accountant", "data analyst"], "site": "SG", "dateRange": 7, "maxItems": 200}
```

# Actor input Schema

## `keywords` (type: `array`):

One search per line, e.g. "python developer", "registered nurse".

## `site` (type: `string`):

Which site to search.

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

Where, as typed on the site: "All Sydney NSW", "Melbourne", "Kuala Lumpur". Empty = whole country.

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

SEEK, Jobstreet or JobsDB search URLs, e.g. https://www.seek.com.au/python-developer-jobs/in-All-Sydney-NSW?daterange=7\&worktype=242 - the site's own filters in the URL are kept.

## `dateRange` (type: `integer`):

Only jobs listed in the last N days (the site's daterange filter). 0 = any time.

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

The date sort value is read from the site's answer on every run.

## `scrapeDetails` (type: `boolean`):

One extra request per job for the full HTML description and the expiry date. Off = list fields (teaser, bullet points) only.

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

Stop after this many jobs. SEEK Australia returns at most about 500 jobs per search (measured).

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

Residential proxy is recommended and is the default.

## Actor input object example

```json
{
  "keywords": [
    "python developer"
  ],
  "site": "AU",
  "location": "All Sydney NSW",
  "dateRange": 0,
  "sortBy": "relevance",
  "scrapeDetails": true,
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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": [
        "python developer"
    ],
    "location": "All Sydney NSW",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("neuro-scraper/seek-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 = {
    "keywords": ["python developer"],
    "location": "All Sydney NSW",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("neuro-scraper/seek-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 '{
  "keywords": [
    "python developer"
  ],
  "location": "All Sydney NSW",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call neuro-scraper/seek-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,neuro-scraper/seek-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/QuWG7Wvd6OGB48yFN/builds/RWHO42ywWR8fZbboz/openapi.json
