# SEEK, JobStreet & JobsDB Jobs Scraper (`anxuanng/seek-jobs-scraper`) Actor

Scrape job ads from SEEK (Australia, New Zealand), JobStreet (Malaysia, Singapore, Philippines, Indonesia) and JobsDB (Hong Kong, Thailand) in one schema: title, company, location, classification, work type, salary range, listing date, full description. Only-new mode for monitoring.

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

## Pricing

from $1.50 / 1,000 job scrapeds

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

## SEEK, JobStreet & JobsDB Jobs Scraper – 8 countries, one schema

Scrape job ads from the whole **SEEK network** in one run: **SEEK** (Australia, New Zealand), **JobStreet**
(Malaysia, Singapore, Philippines, Indonesia) and **JobsDB** (Hong Kong, Thailand). Every site comes back in the
same flat schema: title, company, location, classification, work type, **salary range**, listing date, teaser,
bullet points and, optionally, the full job description.

### What data can I get?

| Field | Example |
|---|---|
| `id`, `site`, `country`, `jobId` | `SG:94584594`, `SG`, `Singapore`, `94584594` |
| `title` | `Electrical Project Manager` |
| `company`, `advertiserName`, `companyProfileUrl` | `Sunley M & E Engineering`, `Sunley M&E Engineering Pte Ltd`, company page on the site |
| `location`, `area`, `suburb` | `Kallang, Central Region`, `Central Region`, `Kallang` |
| `classification`, `subClassification` | `Engineering`, `Electrical/Electronic Engineering` |
| `workType`, `workArrangement` | `Full time`, `On-site` |
| `salaryText` | `$5,500 – $7,500 per month` (as the advertiser wrote it) |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | `5500`, `7500`, `SGD`, `month` |
| `listedAt`, `expiresAt` | ISO dates (`expiresAt` with full description on) |
| `teaser`, `bulletPoints`, `tags` | short summary, the ad's 3 selling points, `["Urgently hiring"]` |
| `isFeatured` | `true` for paid/promoted placements |
| `description`, `isExternalApply` | full description as plain text, and whether applications go to the employer's own site (full description on) |
| `logoUrl`, `url` | company logo, job page |

Salary fields are read from the salary label the advertiser publishes. Many ads show no salary or only prose
("Competitive package"); those rows keep `salaryText` and leave the numbers empty rather than guessing. Currency is
the site's own (MYR, SGD, PHP, IDR, HKD, THB, AUD, NZD) unless the ad says USD.

Example row:

```json
{
  "id": "SG:94584594",
  "site": "SG",
  "country": "Singapore",
  "jobId": "94584594",
  "title": "Electrical Project Manager",
  "company": "Sunley M & E Engineering",
  "advertiserName": "Sunley M&E Engineering Pte Ltd",
  "location": "Kallang, Central Region",
  "area": "Central Region",
  "suburb": "Kallang",
  "classification": "Engineering",
  "subClassification": "Electrical/Electronic Engineering",
  "workType": "Full time",
  "workArrangement": "On-site",
  "salaryText": "$5,500 – $7,500 per month",
  "salaryMin": 5500,
  "salaryMax": 7500,
  "salaryCurrency": "SGD",
  "salaryPeriod": "month",
  "listedAt": "2026-09-11T12:01:49.000Z",
  "teaser": "We are looking for an experienced electrical project manager who will enrich career with us.",
  "bulletPoints": ["Great benefits", "Great platform for improvement", "Friendly working environment"],
  "tags": ["Be an early applicant"],
  "isFeatured": false,
  "url": "https://sg.jobstreet.com/job/94584594"
}
```

### How much does it cost?

**$1.50 per 1,000 jobs.** With **Include full description** on, add **$1.00 per 1,000 jobs** for the extra detail
request. You pay only for jobs delivered to your dataset: 100 jobs cost $0.15 (or $0.25 with descriptions).

### How do I use it?

1. Pick the sites (for example Malaysia and Singapore) and type keywords such as `data engineer`.
2. Optionally narrow by location, classification, work type, days since posting or minimum salary.
3. Run, then download JSON, CSV or Excel, or call the API.

```json
{
  "sites": ["MY", "SG", "AU"],
  "keywords": "data engineer",
  "classifications": ["6281"],
  "workTypes": ["full-time"],
  "postedWithinDays": 7,
  "includeDetails": false,
  "onlyNewJobs": false,
  "maxItems": 1000
}
```

With several sites the Actor takes jobs from each site in turn, so a run of 300 jobs over four sites returns
about 75 from each instead of 300 from the first.

### How do I get only new jobs every day?

Turn on **Only new jobs**, keep **Sort by: Newest first**, and schedule the Actor daily. Each run returns only
jobs you haven't received before and stops reading a site as soon as it reaches jobs you already have. Jobs cut off
by your spending limit are not marked as seen and come back on the next run.

### Use cases

- **Recruiting and sourcing:** track every opening in your niche across Southeast Asia and Australia in one sheet.
- **HR analytics and salary benchmarking:** compare advertised pay by classification, city and country.
- **Sales prospecting:** companies hiring for a role are buying signals; `companyProfileUrl` and `advertiserName`
  help you match them to your CRM.
- **Job boards and aggregators:** feed fresh ads from eight markets with one integration.

### FAQ

**Is it legal?** The Actor reads the public job search that the sites use for their own pages. It does not log in.
It does not collect contact details: phone numbers and recruiter names are never requested or output. A job
description is returned as the advertiser wrote it.

**How many jobs can one run return?** Malaysia, Singapore, Philippines, Indonesia, Hong Kong and Thailand page
through the full result list. SEEK Australia and New Zealand serve at most 550 results per search, so for larger
searches the Actor continues one classification at a time (up to about 550 per classification). For every job in a
very large category, narrow the search by location or work type.

**Do I need a proxy?** No. The Actor runs without one; if a site blocks the platform's network it switches that
site to Apify residential proxy in the site's country on its own.

**Why is `salaryMin` empty for some jobs?** The ad shows no figure, or only text like "Competitive". The
**Minimum salary** filter is applied by the site itself and also covers ads that hide their salary.

**The location filter returned nothing for one site.** Locations are matched per site. "Penang" exists only in
Malaysia, so the Australian site is skipped with a note in the log.

### More scrapers by the same developer

- [ATS Jobs Scraper](https://apify.com/anxuanng/ats-jobs-scraper): Job postings straight from company career boards on Greenhouse, Lever, Ashby, Workday, Workable, Recruitee and SmartRecruiters in one schema, with salary ranges and an only-new mode.
- [Chotot Scraper](https://apify.com/anxuanng/chotot-scraper): Scrape Chợ Tốt (chotot.com), Vietnam's largest classifieds site: cars, motorbikes, real estate, phones, laptops and more, with prices in VND, location and all item attributes. Pay per listing.
- [Prediction Markets Scraper](https://apify.com/anxuanng/prediction-markets-scraper): Kalshi and Polymarket markets in one schema: yes/no probabilities, bid/ask, volume, liquidity, close time and results, with keyword and category filters and an only-changed mode for monitoring.
- [Substack Scraper](https://apify.com/anxuanng/substack-scraper): Posts from any Substack newsletter with likes, comments, word count, free or paid flag and the full text of free posts. Search publications by keyword; only-new mode for monitoring.
- [Telegram Channel Scraper](https://apify.com/anxuanng/telegram-channel-scraper): Scrape public Telegram channels: posts, views, reactions, media, links, forwards, plus channel stats. Incremental mode for daily monitoring. Pay per post.
- [Vietnam Jobs Scraper](https://apify.com/anxuanng/vietnam-jobs-scraper): Scrape job postings from VietnamWorks, TopCV and ITviec in one unified schema. Extract title, company, salary in VND/USD, location, level, skills, deadline and full description. Pay per job, JSON/CSV export, API and MCP access.

# Actor input Schema

## `sites` (type: `array`):

Which job sites to search. JobStreet: Malaysia, Singapore, Philippines, Indonesia. JobsDB: Hong Kong, Thailand. SEEK: Australia, New Zealand. With several sites the jobs are taken from each site in turn, so even a small Max jobs covers all of them.

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

What you would type in the site's search box: a job title, skill or company, e.g. 'data engineer' or 'nurse'. Leave empty for all jobs.

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

City, state or region as the site knows it, e.g. 'Kuala Lumpur', 'Sydney NSW', 'Bangkok'. Applied to every chosen site; a site where the place does not exist returns nothing. Leave empty for the whole country.

## `classifications` (type: `array`):

Job categories (SEEK classifications, the same on all eight sites). Leave empty for all.

## `workTypes` (type: `array`):

Keep only these work types. Leave empty for all.

## `postedWithinDays` (type: `integer`):

Keep only jobs listed in the last N days, e.g. 1 for today's jobs. Leave empty for all open jobs.

## `salaryMin` (type: `integer`):

Keep jobs paying at least this much, in each site's local currency and the period below (e.g. 5000 monthly in Malaysia, 100000 annual in Australia). The site applies it, including to ads that do not show their salary. Leave empty for no salary filter.

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

Period of the Minimum salary. Asian sites mostly publish monthly pay, SEEK Australia and New Zealand annual pay.

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

Newest first is best for monitoring and with Only new jobs; relevance ranks by how well the ad matches the keywords.

## `includeDetails` (type: `boolean`):

Fetch each job's full description (plain text), closing date and whether applications go to the employer's own site. One extra request per job, charged as a separate 'detail' event. Search results already include title, company, location, salary, work type, classification, teaser and bullet points.

## `onlyNewJobs` (type: `boolean`):

Return only jobs you have not received in earlier runs of this Actor. Turn this on for scheduled daily monitoring so you never pay twice for the same job.

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

Stop after this many jobs across all sites. You are only charged per job delivered.

## Actor input object example

```json
{
  "sites": [
    "MY",
    "SG"
  ],
  "keywords": "engineer",
  "salaryPeriod": "monthly",
  "sortBy": "date",
  "includeDetails": false,
  "onlyNewJobs": false,
  "maxItems": 1000
}
```

# Actor output Schema

## `listings` (type: `string`):

All job rows as JSON; append ?format=csv for CSV or ?format=xlsx for Excel.

## `runSummary` (type: `string`):

Counts of pushed/skipped/failed rows and whether the budget limit was hit.

# 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 = {
    "sites": [
        "MY",
        "SG"
    ],
    "keywords": "engineer"
};

// Run the Actor and wait for it to finish
const run = await client.actor("anxuanng/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 = {
    "sites": [
        "MY",
        "SG",
    ],
    "keywords": "engineer",
}

# Run the Actor and wait for it to finish
run = client.actor("anxuanng/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 '{
  "sites": [
    "MY",
    "SG"
  ],
  "keywords": "engineer"
}' |
apify call anxuanng/seek-jobs-scraper --silent --output-dataset

```

## MCP server setup

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