JobsDB Scraper — Thailand & Hong Kong Jobs
Pricing
Pay per usage
JobsDB Scraper — Thailand & Hong Kong Jobs
Scrape JobsDB job listings from Thailand and Hong Kong. Returns 38 fields per job including the full description and parsed salary. Incremental mode returns only new, updated or expired listings with no speed penalty.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Very Banana
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
JobsDB Scraper
Scrape job listings from JobsDB — Thailand and Hong Kong.
Returns 38 structured fields per job, including the full job description, parsed salary range, classification and work arrangement. No login, no cookies, no browser automation.
Why this scraper
| This Actor | |
|---|---|
| Speed | 100 jobs with full descriptions in ~10 seconds |
| Descriptions | Included by default — not a paid extra that slows the run |
| Incremental mode | Returns only new / updated / expired jobs, with no speed penalty |
| Coverage | Both JobsDB sites (TH, HK) from a single input |
| Output | 38 fields, consistent camelCase naming |
It reads JobsDB's own JSON endpoints instead of rendering pages in a browser, which is why it stays fast even when descriptions are included.
Quick start
{"keyword": "developer","country": "th","maxResults": 100}
That returns 100 developer jobs in Thailand with full descriptions.
Incremental mode — pay only for what changed
Running the same search every day usually means paying for the same jobs again. Turn on incrementalMode and the Actor compares against the previous run and returns only what actually changed:
{"keyword": "developer","country": "th","incrementalMode": true,"stateKey": "th-developer-daily"}
Every record carries a changeType of new, updated, expired or unchanged. When a job is updated, changedFields tells you exactly what moved — title, salary or description. Unchanged jobs are filtered out unless you set emitUnchanged.
This costs no extra time: the comparison runs on data already fetched.
Input
| Field | Type | Description |
|---|---|---|
keyword | string | Job title or keyword, e.g. software developer |
country | string | th, hk, sg, id, my, ph |
location | string | City or region filter, e.g. Bangkok |
startUrls | array | Direct JobsDB search URLs |
maxResults | integer | Max jobs to return (0 = unlimited) |
maxPages | integer | Max search pages to crawl |
sortBy | string | relevance or date |
dateRange | string | Posted within 1 / 3 / 7 / 14 / 30 days |
workType | string | Full time, part time, contract, casual |
salaryMin | integer | Minimum advertised salary |
includeDescription | boolean | Full description text and HTML (default true) |
incrementalMode | boolean | Only changed jobs |
stateKey | string | Identifier for incremental comparison |
emitUnchanged | boolean | Also return unchanged jobs |
proxyConfiguration | object | Apify Proxy (required) |
Output
Each job is one dataset item with 38 fields.
Identity — jobId, url, applyUrl, sourceCountry
Core — title, company, companyId, companyUrl, teaser, bulletPoints
Location — location, locationArea, locationCountry
Classification — classification, classificationId, subClassification, subClassificationId
Employment — workType, workArrangement
Salary — salaryText, salaryMin, salaryMax, salaryCurrency, salaryPeriod
Dates — postedAt, postedAtRelative, scrapedAt
Content — description, descriptionHtml, descriptionLength
Change tracking — changeType, contentHash, firstSeenAt, lastSeenAt, changedFields
Meta — isFeatured, searchQuery, resultPosition
Sample output
{"jobId": "94083698","url": "https://th.jobsdb.com/job/94083698","title": "Full Stack Developer – AI & Internal Tools","company": "Penzilla","location": "Bangkok","locationCountry": "TH","classification": "Information & Communication Technology","workType": "Full time","workArrangement": "On-site","salaryText": null,"postedAt": "2026-08-19T12:30:51Z","description": "About the role\nDevelop and maintain backend systems...","descriptionLength": 1840,"changeType": "new","contentHash": "a1b2c3d4e5f60718"}
A note on salary: JobsDB advertisers publish a salary on roughly a third of listings. When absent, salaryText is null rather than a guess.
Use it from code
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('verybananadata/jobsdb-scraper').call({keyword: 'developer',country: 'th',maxResults: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClientclient = ApifyClient("YOUR_TOKEN")run = client.actor("verybananadata/jobsdb-scraper").call(run_input={"keyword": "developer","country": "th","maxResults": 100,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["title"], item["company"])
Common uses
- Recruitment market research — track which roles and skills are being hired for in Southeast Asia
- Salary benchmarking — aggregate
salaryMin/salaryMaxby classification and location - Competitor hiring signals — monitor a company via
companyIdto see when it expands a team - Job board aggregation — feed listings into your own board or newsletter
- Daily monitoring — incremental mode surfaces only new postings each morning
Supported countries
| Code | Site |
|---|---|
th | th.jobsdb.com — Thailand |
hk | hk.jobsdb.com — Hong Kong |
JobsDB operates in Thailand and Hong Kong. Its former Singapore site now redirects to Jora, and Malaysia and the Philippines moved to JobStreet, so those are out of scope for this Actor.