Naukri Jobs Scraper — India + Gulf, drop-in compatible
Pricing
from $1.00 / 1,000 job listings
Naukri Jobs Scraper — India + Gulf, drop-in compatible
Drop-in for valig/naukri-jobs-scraper and muhammetakkurtt/naukri-job-scraper — both input and output vocabularies in one actor. Public job listings from Naukri.com (India) and NaukriGulf.com: title, company, location, salary, experience, skills, apply link, UTC posted-at.
Pricing
from $1.00 / 1,000 job listings
Rating
0.0
(0)
Developer
DIOPSIDE AI
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Share
Naukri Jobs Scraper — India + Gulf
Drop-in compatible with valig/naukri-jobs-scraper and muhammetakkurtt/naukri-job-scraper — both input vocabularies, both output vocabularies, both job boards, one actor. Public job listings from Naukri.com (India) and NaukriGulf.com (UAE, Saudi Arabia, Qatar, Egypt and the rest of MENA), as clean JSON. No login, no proxy, no browser.
Switching from either incumbent means changing the actor id. Nothing else.
Why this one
The Naukri cluster is crowded and the leaders work. This actor is not here to fix a broken scraper; it is here to remove the three things that cost you time once the data is in your warehouse.
1. One actor instead of two. valig emits nested records (id, url, company{}, salary{}, experience{}, skills{}, description{}, locations[]). muhammetakkurtt emits flat ones (jobId, jdURL, companyName, salaryDetail{}, experienceText, tagsAndSkills, jobDescription, location). Both vocabularies are in every record here, side by side, so whichever one your code already parses keeps working. Their input field names both work too — keyword and keywords, maxJobs and limit, freshness and jobAge, workMode: ["remote"] and wfhType: ["2"], sortBy: "date" and sort: "f".
2. Timestamps you can actually sort on. Naukri's own API dates a search result in UTC, dates the same posting's job page in IST, sometimes sends that field as a formatted string and sometimes as a bare epoch — and labels none of it. Every record here carries postedAt, one ISO-8601 UTC timestamp, plus postedDaysAgo. Naukri's original strings are kept beside it in createdDateText so you can check the work.
3. Salary you can filter on. Most Indian postings hide the salary, and both boards will happily tell you the salary is visible while carrying no number — Naukri zeroes the figures, NaukriGulf sends IsCtcHidden: "false" with the CTC fields empty. salaryDisclosed is true only when there is a real number to read, and salaryMinLpa / salaryMaxLpa give it in lakh per annum instead of raw rupees.
And one thing you will hopefully never notice: the filters you asked for are checked against the postings that come back before anything is pushed. Both Naukri APIs answer 200 with a plausible-looking payload when a parameter name is not the one they expect — ask NaukriGulf for query=python&location=dubai in the obvious lower-case spelling and you get 39,410 unrelated jobs and no error at all. If a whole page of results contradicts a filter you set, the run fails loudly instead of billing you for the wrong data. (verifyFilters: false turns this off.)
Input
| Field | Type | Notes |
|---|---|---|
jobBoard | "naukri" | "naukrigulf" | Default naukri. A start URL picks its own board, so one run can mix both. |
keyword | string | Skills, designation or company. Alias: keywords. |
location | string | Bangalore, Pune, Dubai, Saudi Arabia... |
searchUrl | string | Paste a naukri.com / naukrigulf.com search URL. Its query string is carried through, so filters with no field below still work. |
startUrls | array | Several search URLs and/or individual job URLs. |
jobIds | array | 12-digit job ids or full job URLs; skips search entirely. |
maxJobs | integer | Default 100, 0 for everything. Alias: limit. |
fetchDetails | boolean | Full description, role, industry, department, education, view/apply counts, company address. Default off for Naukri.com, on for NaukriGulf, whose search results carry no description at all. |
outputFormat | "normalized" | "raw" | raw emits the API record exactly as muhammetakkurtt/naukri-job-scraper does. |
verifyFilters | boolean | Default true. See above. |
sortBy | "relevance" | "date" | Alias: sort ("r" / "f"). |
experience | string / integer | Years, or "all". |
freshness | "1"–"30" | Days. Alias: jobAge. |
workMode | array | office, remote, hybrid. Alias: wfhType ("0", "2", "3"). |
postedBy | array | "1" company, "2" consultant. Alias: jobPostType. |
cities, department, industry, roleCategory, role, companyType, salaryRange, topCompanies, ugCourse, pgCourse, employmentType, walkin, walkinDate | arrays / booleans | Naukri.com id filters. Every record carries the ids it matched (locations[].gId, roleCategoryGid), so one run tells you the values to use next. |
country, gulfCity, gulfIndustry, gulfFunctionalArea, gulfSalaryRange, nationality, gender, language | arrays / string | NaukriGulf cluster filters. |
urlParam | key/value list | Passed straight to the search API. Repeat a key to mean "both of these". |
proxyConfiguration | object | Off by default — Naukri answers Apify's egress directly. |
residentialFallback | boolean | Default true: if the configured tier ever gets blocked, retry once on residential in-country (IN / AE) rather than failing. A healthy run never pays residential bandwidth. |
Output
One record per posting. Abridged, from a live run:
{"jobId": "210926001708","id": "210926001708","jobBoard": "naukri","title": "Python Developer","url": "https://www.naukri.com/job-listings-python-developer-tata-consultancy-services-pune-chennai-bengaluru-4-to-8-years-210926001708","jdURL": "https://www.naukri.com/job-listings-python-developer-...-210926001708","companyName": "Tata Consultancy Services","company": {"id": 892542, "name": "Tata Consultancy Services","jobsUrl": "https://www.naukri.com/tata-consultancy-services-jobs-careers-13542","overviewUrl": "https://www.naukri.com/tata-consultancy-services-overview-223346","address": "Gachibowli, Rangareddy Hyderabad, Telangana, India"},"location": "Pune, Chennai, Bengaluru","locations": [{ "gId": "97", "label": "Pune", "url": "https://www.naukri.com/jobs-in-pune" }],"workMode": "office","experienceText": "4-8 Yrs","experience": { "text": "4-8 Yrs", "minimum": "4", "maximum": "8" },"salaryDisclosed": false,"salaryMinLpa": null,"salaryMaxLpa": null,"salaryDetail": { "minimumSalary": 0, "maximumSalary": 0, "currency": "INR", "hideSalary": true },"tagsAndSkills": "Pandas,Pytest,Numpy,Python","skills": { "preferred": ["Pandas", "Pytest", "Numpy", "Python"], "other": ["Data Handling", "Github"] },"jobDescription": "<p>Required Technical Skill Set ...</p>","description": { "full": "<p>Required Technical Skill Set ...</p>", "short": "4+ years Python development ..." },"postedAt": "2026-09-21T04:24:45Z","postedDaysAgo": 0,"createdDate": 1789964685000,"createdDateText": "2026-09-21 04:24:45","role": "Software Development - Other","roleCategory": "Software Development","industry": "IT Services & Consulting","department": "Engineering - Software & QA","employmentType": "Full Time, Permanent","education": { "ug": ["Any Graduate"], "pg": [], "ppg": [] },"vacancy": 10,"viewCount": 162,"applyCount": 102,"companyRating": 3.2,"totalResults": 1929,"searchPage": 1,"position": 1,"hasDetails": true}
role, industry, department, education, viewCount, applyCount, the company address and the full jobDescription need fetchDetails: true. hasDetails tells you per record whether the job page was read, so an absent field is never ambiguous.
Public job listings only. Nothing about candidates, applicants or recruiters is collected. nationality and gender reflect preferences the employer published on the advert itself.
Switching from an incumbent
From valig/naukri-jobs-scraper — change the actor id. keywords, location, sort, jobAge, wfhType, experience, jobPostType, limit and urlParam all keep working, and the nested id/url/company/salary/experience/skills/description/locations fields are in every record. Set fetchDetails: true to match their depth (they always read the job page).
From muhammetakkurtt/naukri-job-scraper — change the actor id. jobBoard, keyword, searchUrl, jobIds, maxJobs, fetchDetails, sortBy, experience, freshness, workMode, cities, department, salaryRange, companyType, roleCategory, role, walkin, walkinDate, ugCourse, pgCourse, postedBy, industry, topCompanies, location, language, nationality, country, gulfCity, gulfIndustry, gulfFunctionalArea, gulfSalaryRange and gender are all accepted. Set outputFormat: "raw" for their exact record shape, or leave it on normalized to get their field names plus everything else.
Two differences worth knowing: maxJobs here has no 50-job minimum, and outputFormat: "raw" applies to search results — a jobIds fetch always returns the normalized record, which contains a superset of the same information.
Sizes, speed and cost
Measured on the platform, 1 GB, no proxy:
| Run | Records | Time | Requests |
|---|---|---|---|
Naukri.com, keyword + location + freshness, fetchDetails: true | 40 | 20 s | 43 |
| NaukriGulf, keyword + location, details on | 30 | 12 s | 31 |
| Naukri.com canary, 25 jobs with details | 25 | 14 s | 28 |
Naukri.com pages 20 results at a time and NaukriGulf 30; fetchDetails adds one request per posting. NaukriGulf stops paginating at 45,000 results, which the run reports rather than looping.
Use cases
- Job-market tracking: titles, skills, experience bands and salary distributions by city, role category or industry, over time.
- Recruitment intelligence: which employers are hiring for what, at what seniority, with
applyCountandvacancyas demand signals. - Salary benchmarking on the minority of postings that publish numbers —
salaryDisclosedgets you that subset in one filter. - Job-board and aggregator feeds:
postedAtplusfreshness: "1"gives a clean daily delta. - Skill-demand analysis from
tagsAndSkills/skills.preferred.
Notes on reliability
- Everything that changes is discovered at run time; no build ids or tokens are hardcoded.
- Duplicate postings across pages are dropped, so 100 records means 100 distinct jobs. Naukri's relevance ordering repeats results between pages more often than you would expect.
- A failed job-page fetch costs that posting its detail fields, never the record.
- Partial failures are reported in the run's status message. The run only fails when nothing at all was produced.
- You are charged once per pushed job, and never for a posting that was not written to the dataset.