Shine Scraper - India Jobs, Salary, Skills & Expiry avatar

Shine Scraper - India Jobs, Salary, Skills & Expiry

Pricing

from $1.83 / 1,000 job returneds

Go to Apify Store
Shine Scraper - India Jobs, Salary, Skills & Expiry

Shine Scraper - India Jobs, Salary, Skills & Expiry

Every job on Shine.com with the salary as two numbers - published on 82% of listings, measured. Plus the skills asked for, the years of experience wanted, every city the role covers, the employer, the industry and the expiry date. Recruiter emails and phone numbers are not collected. Unofficial.

Pricing

from $1.83 / 1,000 job returneds

Rating

0.0

(0)

Developer

NeverEmpty

NeverEmpty

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

12 hours ago

Last modified

Share

Pull jobs from Shine.com — one of India's largest job boards — as clean JSON, with the part most job feeds leave out: the salary, on 82% of listings, as two numbers in INR per year.

Unofficial. This Actor is not affiliated with, endorsed by, or sponsored by Shine.com. All product names are trademarks of their respective owners.

No API key. Reads the same public pages a visitor sees.


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] becomes null — never a zero, never a string pretending to be a number
  • Rs 14 - 26 Lakh/Yr becomes salaryMin: 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.


Input

FieldTypeDefaultDescription
keywordstringdeveloperJob title or skill. Spaces become hyphens
citystringbangalore, mumbai, delhi, hyderabad, pune
maxJobsinteger201-1000. One job = one row = one charged event
includeDescriptionbooleantrueFull advert text, HTML stripped, contacts removed
keywordsarrayKeep only jobs containing one of these words
keywordMatchstringanyany or all
excludeKeywordsarrayDrop jobs containing one of these
companyNamesarrayKeep only these employers (partial match)
minSalaryinteger0INR per year. A job with no published salary is kept
requireSalarybooleanfalseDrop the ~18% that hide the salary
postedWithinDaysinteger00 = no limit. An unreadable date is kept
monitoringModebooleanfalseReturn only jobs not returned on a previous run
resetMonitoringStatebooleanfalseOne-shot: forget what was already returned
useProxybooleantrueRoute through an Apify proxy
maxPagesinteger0Safety 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

statuswhen
no-resultsShine has no jobs for this search. That is its answer, not a failure
unreadableThe 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.txt was fetched on 2026-09-04: the User-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.