# TopJobs.lk Scraper — Sri Lanka Job Vacancies & Employers (`bareezh_codes/topjobs-lk-jobs-scraper`) Actor

Scrape every live vacancy on TopJobs.lk, Sri Lanka's largest job portal, capturing title, employer, salary, location, category, and closing date for recruiters, staffing agencies, and labour-market researchers.

- **URL**: https://apify.com/bareezh\_codes/topjobs-lk-jobs-scraper.md
- **Developed by:** [Salman Bareesh](https://apify.com/bareezh_codes) (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.40 / 1,000 results

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

Scrape live job vacancies from **TopJobs.lk**, Sri Lanka's largest job portal, capturing title, employer, location, category, posted/closing dates, and a link to the full job-ad image — for recruiters, staffing agencies, HR-tech founders, and labour-market researchers who need Sri Lankan hiring data without writing and maintaining their own scraper.

### Why use the TopJobs.lk Scraper?

TopJobs.lk lists thousands of live vacancies at any given time across every industry in Sri Lanka, from IT to hospitality to accounting. Developers already build informal scrapers against it (there's an "unofficial TopJobs.lk API" and several job-market-analysis projects on GitHub) because there's no official API — this actor replaces that brittle, hand-rolled script with a maintained one.

Main capabilities:

- Reads TopJobs.lk's own category-listing pages (`vacancybyfunctionalarea.jsp`), each of which embeds every live vacancy in that category — title, employer, location, posted date, and closing date — in a single response.
- Optionally enriches every vacancy with its detail page: a parsed schema.org `JobPosting` JSON-LD block, the full-size job-ad image URL (TopJobs.lk ads are designed images, not plain text), and employment-type tags (Full Time / Part Time, Permanent, Onsite / Remote).
- Filter by any of TopJobs.lk's 31 job categories, or leave it blank to scrape across all of them.
- Runs on the Apify platform, so you get scheduling (daily/weekly feeds), API and webhook access, and monitoring out of the box.

Typical use cases:

- **Recruitment & staffing agencies** — build a live feed of open roles to source candidates against, or track which employers are hiring right now.
- **Competitor / market intelligence** — see which companies are hiring, for what roles, and in which locations.
- **Labour-market research** — analyze hiring trends by category, region, and employer over time.
- **HR-tech & job aggregators** — pull structured Sri Lankan job data into your own product instead of scraping TopJobs.lk yourself.

### How to use the TopJobs.lk Scraper

1. Click **Try for free** (or **Run**) on this actor's page.
2. Optionally pick a **Category** to narrow results to one of TopJobs.lk's 31 job categories. Leave it as "All categories" to scrape across all of them.
3. Set **Max items** to cap how many vacancies you want back.
4. Toggle **Include full description** off if you only need the fast category-listing summary (no per-job detail-page fetch).
5. Click **Start** and wait for the run to finish.
6. Open the **Dataset** tab and export your vacancies as JSON, CSV, or Excel — or pull them programmatically via the **API** tab.

### How much will it cost to use the TopJobs.lk Scraper?

You pay **$0.002 per result** — no subscription, no charge for anything else.

| Your Apify discount tier | Price per result | 1,000 results |
|---|---|---|
| Free | $0.002 | $2.00 |
| Bronze | $0.0018 | $1.80 |
| Silver | $0.0016 | $1.60 |
| Gold | $0.0014 | $1.40 |
| Platinum / Diamond | $0.0014 | $1.40 |

Apify's free plan includes $5 of monthly credit — enough for 2,500 vacancies at no cost. A typical daily pull of 200 fresh vacancies costs under $0.40.

A run stops automatically once it has returned `maxItems` results or once it hits your run's maximum charge (Apify's pay-per-result cost cap) — so `maxItems` directly controls what a run can cost you.

### Input

All fields are optional — running the actor with an empty input (`{}`) scrapes the first 200 vacancies found, starting from the IT categories. See the **Input** tab for the full configuration schema.

| Field | Type | Default | Description |
|---|---|---|---|
| `category` | string (select) | `""` (all) | Only scrape one of TopJobs.lk's 31 job categories, e.g. `"Accounting/Auditing/Finance"`, `"IT-Sware/DB/QA/Web/Graphics/GIS"`. Leave blank for all categories. |
| `maxItems` | integer | `200` | Maximum number of vacancies to return. |
| `includeFullDescription` | boolean | `true` | Fetch each job's detail page for the posted/closing dates, full-size ad-image URL, and employment-type tags. Turn off for a much faster run that only returns the category-listing summary. |

Example input for "the first 50 live IT-Telecoms vacancies, fast, without detail-page enrichment":

```json
{
  "category": "IT-Telecoms",
  "maxItems": 50,
  "includeFullDescription": false
}
```

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. One item is produced per vacancy, with the same keys every time (`null` when that data isn't available for a given posting). This is a real item from a live run of this actor (`tests/smoke_input.json`, category `Accounting/Auditing/Finance`):

```json
{
  "jobId": "1547587",
  "title": "Senior Executive - Finance (1)",
  "employer": "Browns Investments PLC",
  "category": "Accounting/Auditing/Finance",
  "location": "Ekala, Western",
  "salary": null,
  "experienceRequired": null,
  "educationRequired": null,
  "postedDate": "2026-09-13",
  "closingDate": "2026-09-27",
  "description": "Please refer to the advertisement.",
  "employmentTags": ["Full Time", "Permanent", "Onsite"],
  "adImageUrl": "https://www.topjobs.lk/logo/0000000073/1139cVacancy%20o%20Executive%20Financecpageo0001.jpg",
  "applyUrl": "https://www.topjobs.lk/employer/JobAdvertismentServlet?ac=0000000073&ec=0000000432&jc=0001547587&pg=index.jsp",
  "sourceUrl": "https://www.topjobs.lk/employer/JobAdvertismentServlet?ac=0000000073&ec=0000000432&jc=0001547587&pg=index.jsp"
}
```

#### Field reference

| Field | Description |
|---|---|
| `jobId` | TopJobs.lk's internal job reference number |
| `title`, `employer` | Vacancy title and hiring employer's name |
| `category` | The TopJobs.lk functional-area category this vacancy was listed under |
| `location` | City/area and province, when available |
| `salary` | Not published by TopJobs.lk on any vacancy observed — always `null` (see FAQ) |
| `experienceRequired`, `educationRequired` | Not extractable — always `null` (see FAQ) |
| `postedDate`, `closingDate` | Dates the vacancy was posted and closes, `YYYY-MM-DD` |
| `description` | Short text preview from the category listing (often "Please refer the advertisement" — the real ad is an image, see `adImageUrl`) |
| `employmentTags` | Employment-type labels shown on the vacancy, e.g. `["Full Time", "Permanent", "Onsite"]`; `null` if `includeFullDescription` is off |
| `adImageUrl` | Direct link to the full-size job-ad image (the actual job description); `null` if `includeFullDescription` is off |
| `applyUrl`, `sourceUrl` | Link to the vacancy's page on TopJobs.lk |

### FAQ, disclaimers, and support

**Is this legal?** Yes. Every vacancy this actor returns is a live, public job advertisement that TopJobs.lk itself displays to any visitor without a login. This actor only reads TopJobs.lk's own public pages — no login, no CAPTCHA solving, no third-party data broker.

**Why are `salary`, `experienceRequired`, and `educationRequired` always `null`?** TopJobs.lk renders the actual job description as a designed image (a scanned/graphic ad), not as machine-readable text — that image is exactly what `adImageUrl` links to. The one machine-readable field TopJobs.lk exposes per posting (a schema.org JSON-LD `description`) is a constant placeholder ("Please refer the full details...") on every single vacancy, so it carries no real information. If a future redesign of the site adds these fields as text, this actor will be updated to extract them.

**Why did my run return fewer than `maxItems` results?** Either that category has fewer live vacancies than `maxItems`, or (with `category` left blank) the run reached `maxItems` partway through a category and stopped there — rerun with a larger `maxItems` or pick a specific category to see more of it.

**How fresh is the data?** As fresh as TopJobs.lk itself — vacancies are scraped live from the site's current listing pages on every run.

**Can I get every live vacancy on the site?** Yes — leave `category` blank and set `maxItems` high enough (TopJobs.lk has roughly 3,000-3,500 live vacancies across all categories at any time).

#### Legal & compliance note

All data comes from TopJobs.lk's own public vacancy pages, which the site publishes openly to any visitor without requiring login or payment. This actor identifies itself with a descriptive `User-Agent` and paces its requests politely. It does not collect any personal candidate data — only employer-published job advertisements.

#### Limits & notes

- `salary`, `experienceRequired`, and `educationRequired` are always `null` — TopJobs.lk does not publish this as extractable text on any vacancy (see FAQ).
- `description` is a short preview only; the full ad is the image at `adImageUrl`.
- Some job postings are in Sinhala or Tamil; text fields are passed through as-is (UTF-8).

#### Support

Found a bug or have a feature request? Use the **Issues** tab on this actor's page. For programmatic access, see the **API** tab for ready-made code snippets in your language of choice.

# Actor input Schema

## `category` (type: `string`):

Only scrape vacancies from this TopJobs.lk category. Leave as "All categories" to scrape across every category.

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

Maximum number of vacancies to return. Kept small by default so a run with the default input finishes quickly.

## `includeFullDescription` (type: `boolean`):

Fetch each job's detail page to enrich it with the posted/closing dates, the full-size job-ad image URL and employment-type tags (full-time/part-time, permanent, onsite/remote). Turning this off is much faster but only returns the category-listing summary.

## Actor input object example

```json
{
  "category": "",
  "maxItems": 200,
  "includeFullDescription": true
}
```

# Actor output Schema

## `dataset` (type: `string`):

One item per matching vacancy

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("bareezh_codes/topjobs-lk-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("bareezh_codes/topjobs-lk-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 '{}' |
apify call bareezh_codes/topjobs-lk-jobs-scraper --silent --output-dataset

```

## MCP server setup

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