LinkedIn Jobs Scraper (No Login)
Pricing
Pay per usage
LinkedIn Jobs Scraper (No Login)
Scrape public LinkedIn job listings by keyword, location or search URL. No cookies, no account. Exports title, company, salary, description, seniority, applicants and more.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Genius_Coder Sam
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
23 days ago
Last modified
Categories
Share
Scrape public LinkedIn job listings by keyword, location or search URL, and export clean structured data (JSON, CSV, Excel, API). No LinkedIn account, no cookies, no login — the Actor reads the same public job pages any logged-out visitor can see.
What you get
For every job:
| Field | Example |
|---|---|
id, url (alias: link) | 4012345678, https://www.linkedin.com/jobs/view/… |
title, companyName, companyUrl (alias: companyLinkedinUrl), companyLogo | Senior Software Engineer, Acme Corp |
companyDescription, companyWebsite, companyEmployeesCount | from the company's own LinkedIn page — fetched once per unique company, only when Scrape full job details is on |
location, postedAt, postedAtText, postedAtTimestamp | Bangkok, Thailand, 2026-09-18, 3 days ago, 1768694400000 |
salary (alias: salaryInfo, same value wrapped in an array) | ฿120,000/mo - ฿180,000/mo (when the employer shows it) |
benefits | ["Actively Hiring"] — a recruiting-engagement badge LinkedIn shows on the search card, not real employer benefits; empty array when the badge isn't shown |
employmentType, seniorityLevel, jobFunction, industries | Full-time, Mid-Senior level … |
applicantsCount, applicantsText (alias: applicants) | 200, Over 200 applicants |
applyUrl | the employer's own apply link when LinkedIn exposes one, otherwise the job's own url |
closedNotice | e.g. "No longer accepting applications" when LinkedIn shows one; null does not mean the job is still open — there's no expiration date/timestamp in guest markup |
descriptionText, descriptionHtml | full job description |
search, scrapedAt | which search produced it, ISO timestamp |
link, companyLinkedinUrl, salaryInfo and applicants are aliases kept alongside the original field names for downstream apps that expect those exact keys — same data, different name/shape.
companyDescription/companyWebsite/companyEmployeesCount cost one extra request per unique company (cached and reused across all of that company's jobs in the same run), not one per job.
How to use
- Either paste one or more search URLs copied from
linkedin.com/jobs/search(set your filters on LinkedIn first), or enter keywords and locations (one search per pair). - Optionally set date posted, experience level, job type, workplace type.
- Set Maximum jobs — you pay per job returned, so this is your budget cap.
- Run. Download results from the Output tab or use the API.
Example input
{"keywords": ["data engineer"],"locations": ["Bangkok, Thailand", "Singapore"],"datePosted": "week","workplaceType": ["remote", "hybrid"],"maxItems": 500,"scrapeJobDetails": true}
Example output (trimmed)
{"id": "4410261275","url": "https://www.linkedin.com/jobs/view/software-engineer-backend-at-plaid-4410261275","link": "https://www.linkedin.com/jobs/view/software-engineer-backend-at-plaid-4410261275","title": "Software Engineer, Backend","companyName": "Plaid","companyUrl": "https://www.linkedin.com/company/plaid-","companyLinkedinUrl": "https://www.linkedin.com/company/plaid-","companyWebsite": "https://plaid.com","companyEmployeesCount": 5060,"location": "New York City Metropolitan Area","postedAt": "2026-09-18","salary": "$176,400.00/yr - $226,800.00/yr","salaryInfo": ["$176,400.00/yr - $226,800.00/yr"],"benefits": ["Actively Hiring"],"employmentType": "Full-time","seniorityLevel": "Mid-Senior level","applicantsCount": 200,"applicants": "Over 200 applicants","applyUrl": "https://www.linkedin.com/jobs/view/software-engineer-backend-at-plaid-4410261275","closedNotice": null,"descriptionText": "About the role …"}
Options worth knowing
- Scrape full job details — on (default) opens every job page for the description and metadata; off gives a faster, cheaper listing-only run.
- Break the 1,000-result limit — LinkedIn shows at most ~1,000 results per search. When a search hits that limit, the Actor automatically splits it by job type, experience level and workplace type to reach more jobs, and de-duplicates across the splits. In practice this has diminishing returns for broad searches: LinkedIn's job-type/experience/workplace facets tend to overlap heavily with the unfiltered top 1,000, so a split can spend a lot of extra requests (and proxy budget) re-fetching jobs you already have before it turns up genuinely new ones. It's most worth enabling for narrower searches, or when you specifically need more than ~1,000 results and are prepared to pay for the extra paging.
- Proxy — residential proxies are strongly recommended. LinkedIn blocks datacenter IPs.
- Max concurrency — lower it if you see blocked requests.
Limits and honest notes
- Only publicly visible data is collected. Anything that requires logging in (e.g. some recruiter details, "insights") is not available.
applyUrlis almost never the employer's real apply link. LinkedIn now hides that target (internal or external) behind a "sign in to apply" modal for logged-out visitors, so it only gets exposed on the rare posting that still leaks it in guest markup — every other job falls back to that job's ownurlinstead ofnull, soapplyUrlalways points somewhere useful.salaryreflects the employer-provided pay range and is only present when LinkedIn shows one; most postings don't have it.- Not implemented, confirmed unavailable in guest markup: who posted/recruits for a job (needs a signed-in session), a real "salary insights" comparison (separate from the employer's own posted range, which
salary/salaryInfoalready cover), and a structured apply-method/workplace-type signal — mentions of "remote"/"hybrid" only turn up as incidental words inside the free-text description, not a labeled field. - LinkedIn changes its pages and blocking rules often. If a run returns fewer jobs than expected, retry with lower concurrency; report persistent problems in the Issues tab.
- Results depend on what LinkedIn shows logged-out visitors for your query and location, and may differ from what you see when signed in.
Is it legal?
The Actor accesses only public pages without logging in. Laws and platform terms differ by country and by how you use the data, and LinkedIn's User Agreement restricts automated access. You are responsible for using the data lawfully — in particular, do not use it to profile private individuals, and comply with GDPR/CCPA if you store any personal data (such as recruiter names). This is not legal advice.
Local development
npm installnpm test # parser + query unit tests (offline)npm run test:e2e # full actor run against a local mock of LinkedIn's endpointsapify run # run locally with storage/key_value_stores/default/INPUT.jsonapify push # deploy to your Apify account
Selectors and endpoint URLs live in src/linkedin.js only — that is the file to update when LinkedIn changes its markup.