Shine Scraper & New-Job Monitor - India Jobs, Salary & Skills
Pricing
from $1.83 / 1,000 job returneds
Shine Scraper & New-Job Monitor - India Jobs, Salary & Skills
For India recruitment, salary benchmarking and job boards: Shine.com listings as clean JSON with the salary as two numbers in INR per year, on 66 of 80 listings measured on 2026-09-04. Developer showed 38,305 jobs nationwide, 4,923 in Bangalore. Monitoring returns only new jobs.
Pricing
from $1.83 / 1,000 job returneds
Rating
0.0
(0)
Developer
NeverEmpty
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Shine Scraper - India Jobs, Salary, Skills & Expiry
For Indian salary benchmarking, recruitment market research and feeding a job board: jobs from Shine.com — one of India's largest job boards — as flat rows, with the part most job feeds leave out: the salary, on 82% of listings, as two numbers in INR per year.
Measured on 80 live listings on 2026-09-04: 66 of 80 (82%) publish a salary. That is far more than most boards. Rs 14 - 26 Lakh/Yr becomes salaryMin: 1400000, salaryMax: 2600000, salaryCurrency: "INR", salaryPeriod: "year" — Indian Lakh notation read correctly, never as 14. Volume on the same day: developer 38,305 jobs nationwide and 4,923 in Bangalore, accountant 12,768, nurse 1,110.
One request per page, not one per job. Shine ships the whole job — description, salary, location, experience, expiry — inside the listing page itself, so this Actor reads all twenty fields from that single page and never opens individual job pages. 200 jobs costs 10 requests.
A city Shine does not recognise is reported, not answered with the whole country. Measured on 2026-09-11, a spelling Shine does not know (delhi-ncr, greater-noida, trivandrum, vizag, remote) leaves the location empty and Shine quietly returns all of India — 286,457 jobs. You get one unpaid city-not-recognised row instead of a charged list from the wrong place. Leave the keyword empty to take a whole city (jobs-in-bangalore held 26,829 jobs on 2026-09-11).
No API key. Reads the same public pages a visitor sees, and only paths robots.txt allows. Export as JSON, CSV or Excel.
Unofficial. This Actor is not affiliated with, endorsed by, or sponsored by Shine.com. All product names are trademarks of their respective owners.
Run it tomorrow and you only get what is new
Schedule this Actor with monitoringMode: true and each run returns only the jobs it has not returned before. Not "here is everything again, please de-duplicate it yourself" — the Actor remembers what it already gave you, so a daily feed costs you the handful of new roles, not the whole board every morning. You are never charged for the same job twice.
Jobs your filters removed are remembered too, so widening a filter later does not resurrect them as false "new" jobs. Jobs that did not fit under your limit are not remembered, so they are still waiting on the next run instead of being silently lost.
Why this one is different
Recruiter emails and phone numbers are removed, on purpose
Shine's own page data carries the recruiting contact's personal email address on every listing and a mobile number on most of them — and advertisers often repeat them inside the advert text (Call & Drop Updated cv : 93108… parveen…@gmail.com).
This Actor does not output those fields at all, and it removes email addresses and mobile numbers from the description text as well. Job data, not a contact list. If you need contact data, use a tool that says so.
The salary is there, and it is honest about when it is not
Measured on 80 live listings on 2026-09-04: 66 of 80 (82%) publish a salary. That is far more than most boards.
Shine writes it as text (Rs 14 - 26 Lakh/Yr) and writes the literal string [Salary Hidden] when the employer withheld it. Passing that through would sell you a salary of "[Salary Hidden]", so:
[Salary Hidden]becomesnull— never a zero, never a string pretending to be a numberRs 14 - 26 Lakh/YrbecomessalaryMin: 1400000,salaryMax: 2600000,salaryCurrency: "INR",salaryPeriod: "year"(1 Lakh = 100,000)- any other wording is left as raw text with the numbers
null— a form we have not verified is never guessed into numbers
Codes we have not verified are not translated
Shine marks employment type with a number. Across 80 listings the value was always 1, and the job's own structured data said FULL_TIME — so 1 maps to FULL_TIME and every other code comes back as null with the raw number in employmentTypeCode. A second code (engagementTypeCode) is passed through untranslated because we could not confirm what its values mean.
One request, twenty complete jobs
Shine ships the full job — description, salary, location, experience, expiry — inside the listing page itself. This Actor reads all twenty from that single page, so it never opens individual job pages. 200 jobs costs 10 requests, not 210.
Every city the role covers
A role open in nine cities comes back with all nine in locations. The job's own detail page shows only the first one.
Dates you can actually compare
Shine writes timestamps without a timezone. Its structured data writes the same instant as +05:30, so this Actor attaches India Standard Time rather than letting your database read them as UTC and shift them by five and a half hours. expiresAt tells you whether a vacancy is about to close.
An empty search is an answer, not a silent fallback
A keyword Shine does not have returns zero results with a total count of zero — it never quietly falls back to every job. You get one no-results row saying so, and it is not charged. A page that could not be read at all is a different row (unreadable) carrying the HTTP status.
A city is different, and Shine says what it did inside its own page (query.loc and location_relaxed), which this Actor reads. Measured on 2026-09-11:
- A spelling Shine does not know (
delhi-ncr,greater-noida,trivandrum,vizag,remote) leaves the location empty and Shine returns all of India (286,457 jobs). You get one unpaidcity-not-recognisedrow instead.delhi,noidaandgurgaonare recognised, but each of the three returns the whole Delhi capital region (34,334 jobs), not only that city. - A known city with no jobs for your keyword (
gynecologistinhyderabad) makes Shine show jobs from other cities instead. You get one unpaidno-jobs-in-cityrow. - A known city with only a few jobs (
marine engineerinkolkata: 9) makes Shine fill the page with jobs from other cities (11 more). Only the 9 Kolkata jobs are returned and charged, and one unpaidother-cities-left-outrow says how many were left out.
Input
| Field | Type | Default | Description |
|---|---|---|---|
keyword | string | — | Job title or skill. Spaces become hyphens. Leave empty to search every job in city (/job-search/jobs-in-bangalore, 26,829 jobs on 2026-09-11) or all of India. Only when keyword, city, keywords and companyNames are all empty is the example developer used, and every row says so in note. Every row carries searchUrl |
city | string | — | bangalore, mumbai, delhi, hyderabad, pune… |
maxJobs | integer | 20 | 1-1000. One job = one row = one charged event |
includeDescription | boolean | true | Full advert text, HTML stripped, contacts removed |
keywords | array | — | Keep only jobs containing one of these words |
keywordMatch | string | any | any or all |
excludeKeywords | array | — | Drop jobs containing one of these |
companyNames | array | — | Keep only these employers (partial match) |
minSalary | integer | 0 | INR per year. A job with no published salary is kept |
requireSalary | boolean | false | Drop the ~18% that hide the salary |
postedWithinDays | integer | 0 | 0 = no limit. An unreadable date is kept |
monitoringMode | boolean | false | Return only jobs not returned on a previous run |
resetMonitoringState | boolean | false | One-shot: forget what was already returned |
useProxy | boolean | true | Route through an Apify proxy |
maxPages | integer | 0 | Safety cap; 0 = decide from maxJobs (20 per page) |
{ "keyword": "developer", "city": "bangalore", "maxJobs": 100,"keywords": ["python", "aws"], "keywordMatch": "all","excludeKeywords": ["intern"], "minSalary": 1500000 }
Filters are applied before you are charged
The filters narrow the jobs already read — nothing extra is fetched from Shine, and a job that does not match is never delivered and never charged. If a search returns jobs but none match your filters, you get one unpaid row saying exactly that, so you can tell "the filter was too tight" apart from "the board is empty".
Two of them refuse to guess: a job with no published salary is kept by minSalary (an unknown salary is not a low one), and a job with an unreadable posted date is kept by postedWithinDays. Turn on requireSalary if you want the unknowns dropped.
Monitoring mode turns this into a daily feed
Schedule it and set monitoringMode: true: each run returns only the jobs it has not returned before. The first run returns everything and remembers it. Jobs that were read but filtered out are remembered too, so a later change of filters does not resurrect them as false "new" postings. You pay for new postings, not for the same list every morning.
Measured on 2026-09-04: developer 38,305 jobs nationwide and 4,923 in Bangalore, accountant 12,768, nurse 1,110.
Output
One row per job:
{"source": "shine","jobId": "19506404","url": "https://www.shine.com/jobs/backendsenior-csharp-developer/iquest-management-consultants-pvt-ltd/19506404","title": "Backend (Senior C# Developer)","company": "IQuest Management Consultants Pvt Ltd.","companyId": 694125,"industry": "IT Services & Consulting","locations": ["Bangalore", "Noida", "Chennai", "Hyderabad", "Gurugram", "Kolkata", "Pune", "Mumbai City", "Delhi"],"salaryText": "Rs 8 - 18 Lakh/Yr","salaryMin": 800000,"salaryMax": 1800000,"salaryCurrency": "INR","salaryPeriod": "year","experienceText": "5 to 8 Yrs","experienceMinYears": 5,"experienceMaxYears": 8,"skills": ["sql server", "t-sql", "performance tuning", "c#", ".net"],"employmentType": "FULL_TIME","employmentTypeCode": 1,"engagementTypeCode": 2,"postedAt": "2026-08-28T17:20:00+05:30","expiresAt": "2026-10-27T00:00:00+05:30","description": "…","status": "ok","scrapedAt": "2026-09-04T05:20:05.658Z"}
Rows that are never charged
status | when |
|---|---|
no-results | Shine has no jobs for this search. That is its answer, not a failure |
unreadable | The page could not be read, or its embedded data was missing |
A page whose embedded data cannot be found is reported as unreadable, never as "no jobs" — so a redesign on Shine's side shows up as an error rather than as a quiet, permanent "there are no vacancies".
Pricing
Pay per job returned. Rows that report an empty search or a page that could not be read are not charged. A job that appears twice is dropped before delivery, so it is never charged twice.
Notes
robots.txtwas fetched on 2026-09-04: theUser-agent: *section disallows/api/*,/jobs/1*,/jobs/9*,/job-search/simple/and similar. This Actor reads only/job-search/<keyword>-jobs, which is not disallowed.- Only public pages are read. No login, no API key.