LinkedIn Jobs Scraper (No Login) avatar

LinkedIn Jobs Scraper (No Login)

Pricing

Pay per usage

Go to Apify Store
LinkedIn Jobs Scraper (No Login)

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

Genius_Coder Sam

Maintained by Community

Actor 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:

FieldExample
id, url (alias: link)4012345678, https://www.linkedin.com/jobs/view/…
title, companyName, companyUrl (alias: companyLinkedinUrl), companyLogoSenior Software Engineer, Acme Corp
companyDescription, companyWebsite, companyEmployeesCountfrom the company's own LinkedIn page — fetched once per unique company, only when Scrape full job details is on
location, postedAt, postedAtText, postedAtTimestampBangkok, 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, industriesFull-time, Mid-Senior level …
applicantsCount, applicantsText (alias: applicants)200, Over 200 applicants
applyUrlthe employer's own apply link when LinkedIn exposes one, otherwise the job's own url
closedNoticee.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, descriptionHtmlfull job description
search, scrapedAtwhich 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

  1. 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).
  2. Optionally set date posted, experience level, job type, workplace type.
  3. Set Maximum jobs — you pay per job returned, so this is your budget cap.
  4. 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.
  • applyUrl is 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 own url instead of null, so applyUrl always points somewhere useful.
  • salary reflects 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/salaryInfo already 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.

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 install
npm test # parser + query unit tests (offline)
npm run test:e2e # full actor run against a local mock of LinkedIn's endpoints
apify run # run locally with storage/key_value_stores/default/INPUT.json
apify 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.