LinkedIn Jobs Scraper
Pricing
from $1.00 / 1,000 jobs
LinkedIn Jobs Scraper
Scrape LinkedIn jobs from search URLs or filters. Get title, salary, full description, seniority, applicants, apply link, recruiter and company data (website, size, industry). Split searches by city to get past the 1000-job cap. No login or cookies needed. Export to JSON, CSV or Excel.
Pricing
from $1.00 / 1,000 jobs
Rating
0.0
(0)
Developer
Brisk Pebble
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Scrape public LinkedIn job listings, with no login and no cookies. For every job you get the full description, salary, seniority, employment type, applicant count, apply URL, the recruiter who posted it, and a company profile (website, size, industry, headquarters, followers).
Paste LinkedIn job search URLs, or fill in a few filters (keywords, location, date posted, companies). To get past LinkedIn's limit of about 1000 jobs per search, you can split a search across a country's cities.
What can this LinkedIn Jobs Scraper do?
- Search by URL or by filters. Paste any public
linkedin.com/jobs/searchURL, single job URLs (/jobs/view/...), or use keywords, location, geoId, distance, date posted, company IDs, Easy Apply and "under 10 applicants". - Full job details. Description (HTML and plain text), seniority level, employment type, job function, industries, applicant count, salary, external apply URL or Easy Apply, and whether the job is closed.
- Job poster. Name, headline, photo and profile URL of the recruiter, when LinkedIn shows them.
- Company enrichment. Website, employee count, size range, industry, headquarters, postal address, organization type, founding year, specialties, followers, slogan and description. Each company is fetched once per run, however many jobs it has.
- Works with LinkedIn's AI job search. LinkedIn's public search now ignores classic filters like job type, experience, workplace type and salary. This Actor rewrites them into keywords (e.g.
f_WT=2becomes "remote"), so old search URLs still return relevant jobs. - Get past the 1000 results cap. Split a search across the major cities of 30+ countries, or across your own list of locations. Duplicate jobs are removed automatically.
- Pay only for what you want. Title and company exclusions are applied before job pages are opened. You can also turn off details for a fast run that returns search card data only.
- Reliable at scale. Uses residential proxies, session rotation on blocks (HTTP 429/999, auth walls), automatic retries and persisted state, so migrated runs resume without duplicates. If a job page can't be loaded, the job is still saved with its search card data.
How to scrape LinkedIn jobs
- Open linkedin.com/jobs/search in an incognito window. The public search can differ from the logged-in one.
- Search with the filters you want and copy the URL from the address bar.
- Paste it into LinkedIn job search URLs. Alternatively, leave URLs empty and fill in Search filters.
- Set Max jobs per search and click Start.
- Download the results as JSON, CSV, Excel or HTML, or get them through the API.
Input example
{"keywords": "data engineer","location": "United States","datePosted": "pastWeek","workplaceTypes": ["2"],"scrapeCompany": true,"limitPerSource": 200,"titleExcludeKeywords": ["intern"],"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }}
The same search, using a URL:
{"urls": ["https://www.linkedin.com/jobs/search/?keywords=data%20engineer&location=United%20States&f_TPR=r604800&f_WT=2"],"limitPerSource": 200}
Getting every Python job in Germany, past the 1000 cap:
{"keywords": "python","splitByLocation": true,"splitCountry": "DE"}
Input fields
| Field | Description |
|---|---|
urls | LinkedIn job search URLs or job URLs. When set, the search filters are ignored. |
keywords, location, geoId, distance | Search filters used when no URLs are given. |
datePosted | anyTime, pastHour, past24Hours, pastWeek, pastMonth. |
companyIds | LinkedIn numeric company IDs (f_C= in search URLs). |
under10Applicants, easyApply | Boolean URL filters supported by the public search. |
jobTypes, experienceLevels, workplaceTypes, minSalary, sortBy | Classic filters. Rewritten into keywords when autoConvertToAiSearch is on. |
autoConvertToAiSearch | Rewrite unsupported classic filters into keywords (default true). |
scrapeJobDetails | Open every job page (default true). Turn off for a fast run with search card data only. |
scrapeCompany | Add company details (default true). |
limitPerSource | Max jobs per search. Empty means everything LinkedIn returns, up to about 1000. |
maxItems | Max jobs in total across all searches. |
splitByLocation, splitCountry, splitLocations | Run each search once per city to get past the 1000 cap. |
titleExcludeKeywords, companyExcludeNames | Skip unwanted jobs before paying for their details. |
proxyConfiguration | Residential proxy recommended (default). |
maxConcurrency, maxRequestRetries | Performance tuning. |
Output example
{"id": "4012345678","trackingId": "TrackAAA==","refId": "RefAAA==","link": "https://www.linkedin.com/jobs/view/senior-python-developer-at-acme-4012345678","title": "Senior Python Developer","companyName": "Acme Corp","companyLinkedinUrl": "https://www.linkedin.com/company/acme","companyLogo": "https://media.licdn.com/dms/image/acme-logo.png","location": "New York, NY","salary": "$140,000.00/yr - $180,000.00/yr","postedAt": "2026-10-18","postedTimeAgo": "1 day ago","benefits": ["Actively Hiring"],"applicantsCount": "Over 200 applicants","applyUrl": "https://careers.acme.com/jobs/123","applyType": "EXTERNAL","isClosed": false,"descriptionHtml": "<strong>About us</strong><br>…","descriptionText": "About us\n\nAcme builds rockets.\n\n• 5+ years of Python","seniorityLevel": "Mid-Senior level","employmentType": "Full-time","jobFunction": "Engineering and Information Technology","industries": "Software Development","jobPosterName": "Jane Doe","jobPosterTitle": "Technical Recruiter at Acme","jobPosterPhoto": "https://media.licdn.com/dms/image/jane.jpg","jobPosterProfileUrl": "https://www.linkedin.com/in/janedoe","companyDescription": "Acme builds rockets for everyone.","companySlogan": "Building the future","companyWebsite": "https://www.acme.com","companyEmployeesCount": 5230,"companySize": "1,001-5,000 employees","companyIndustry": "Software Development","companyHeadquarters": "New York, NY","companyType": "Public Company","companyFounded": "2004","companySpecialties": "Rockets, Anvils","companyFollowers": 120345,"companyAddress": { "type": "PostalAddress", "streetAddress": "1 Main St", "addressLocality": "New York", "addressRegion": "NY", "postalCode": "10001", "addressCountry": "US" },"inputUrl": "https://www.linkedin.com/jobs/search/?keywords=python","scrapedAt": "2026-10-19T12:00:00.000Z"}
Fields LinkedIn doesn't show for a job are null. A detailError field appears only when the job page couldn't be loaded and the item holds search card data only.
The dataset has three views: Overview, Job details and Companies.
How much does it cost?
The Actor uses lightweight HTTP requests (no browser), so 512 MB of memory is enough. Each job costs one request for its page. Each new company costs one more request, and that result is reused for all of the company's jobs. Turning off Scrape job details cuts the cost to about one request per 10 jobs.
Tips
- Use residential proxies. LinkedIn rate-limits datacenter IPs heavily.
- Need more than ~1000 jobs? Turn on Split search by city locations, or split by date (e.g. run
past24Hoursdaily). - Daily monitoring. Schedule the Actor with
datePosted: "past24Hours"and combine it with an integration (Google Sheets, Slack, webhooks). - Missing jobs? The public search shows fewer results than a logged-in session, and some filters behave differently. Check your URL in an incognito window.
Is it legal to scrape LinkedIn?
This Actor only reads data that LinkedIn shows publicly to logged-out visitors. It doesn't log in, and it doesn't access private profiles. Personal data (such as job poster names) is protected by regulations like GDPR. Only scrape personal data when you have a legitimate reason, and consult a lawyer if you're unsure.
Development
npm installnpm test # unit tests + end-to-end test against a local mock of LinkedInnpm run build # compile TypeScript to dist/apify run # run locally with the input in storage/key_value_stores/default/INPUT.jsonapify push # deploy to the Apify platform
Project layout:
.actor/ Actor definition: actor.json, input, dataset and output schemas, Dockerfilesrc/main.ts Entry point: input, proxy, state and crawler setupsrc/routes.ts SEARCH (pagination, de-duplication, limits) and DETAIL (job + company) handlerssrc/parsers.ts Cheerio parsers for search cards, job pages and company pagessrc/urls.ts Search URL parsing/building and AI-search filter conversionsrc/sources.ts Turns the input into searches, including split by locationsrc/company.ts Per-run company cachesrc/cities.ts City lists used for split by locationtest/ Vitest unit tests, HTML fixtures and an end-to-end testassets/icon/ Actor icon: SVG source and 1024/512/256 px PNGs (upload icon-1024.png in Console)