LinkedIn Jobs Scraper - Professional Job Listings avatar
LinkedIn Jobs Scraper - Professional Job Listings

Pricing

from $3.00 / 1,000 results

Go to Apify Store
LinkedIn Jobs Scraper - Professional Job Listings

LinkedIn Jobs Scraper - Professional Job Listings

Scrapes public job listings from LinkedIn's job board. Filter by location, job type, experience level, and remote options. Extract company info, job descriptions, and application links. No login required.

Pricing

from $3.00 / 1,000 results

Rating

0.0

(0)

Developer

Alessandro Santamaria

Alessandro Santamaria

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

LinkedIn Job Scraper

Scrapes job listings from LinkedIn Jobs - the world's largest professional network with 1B+ members and millions of job postings worldwide.

Three Scraping Modes

This scraper supports three distinct modes for different use cases:

ModeInputOutputUse Case
SEARCH MODESearch query + filtersBasic job data from SERPFast discovery of new jobs
SEARCH + DETAILS MODEincludeJobDetails: trueFull job data with descriptionsComplete data collection in one run
DIRECT URLS MODEdirectUrls: [...]Full job data + job_statusStill-alive checks, re-scraping specific jobs

Features

  • Global coverage - Search jobs in any country or location worldwide
  • Advanced filters - Filter by date posted, job type, experience level, and remote options
  • No login required - Uses LinkedIn's public guest API for job search
  • Job status checks - Verify if jobs are still online, expired, or removed
  • Rich data extraction - Title, company, location, salary, description, apply URL, and more
  • Swiss canton detection - Automatically detects Swiss canton codes from location
  • Standardized output - Consistent JobListing schema across all job scrapers
  • Rate-limited - Respectful delays between requests
  • Proxy support - Built-in proxy rotation for reliability

Input

FieldTypeDescriptionDefault
directUrlsarrayDirect job URLs to scrape (skips search mode)[]
searchQuerystringJob title, skills, or keywords to search for""
locationstringCity, country, or region (e.g., "Zurich", "Switzerland", "Germany")""
datePostedstringFilter by posting date: any, past-24h, past-week, past-monthany
jobTypestringFilter by job type: full-time, part-time, contract, temporary, internship""
experienceLevelstringFilter by experience: entry, associate, mid-senior, director, executive""
remoteFilterstringFilter by workplace: remote, on-site, hybrid""
maxResultsintegerMaximum number of job listings to scrape100
includeJobDetailsbooleanFetch full job descriptions (slower but more data)false
proxyConfigurationobjectApify proxy settingsResidential

Mode 1: SEARCH MODE (Fast)

Search for jobs using keywords and filters:

  • Use case: Discover new jobs, market analysis, broad searches
  • Speed: Fast - uses LinkedIn's guest API
  • Output: Basic job data from search results
{
"searchQuery": "Software Engineer",
"location": "Switzerland",
"datePosted": "past-week",
"jobType": "full-time",
"maxResults": 100
}

Mode 2: SEARCH + DETAILS MODE (Complete Data)

Search with includeJobDetails: true to fetch full descriptions:

  • Use case: Complete data collection in one run
  • Speed: Moderate - visits detail pages for each job
  • Output: Full descriptions, requirements, apply URLs
{
"searchQuery": "Data Scientist",
"location": "Zurich",
"maxResults": 50,
"includeJobDetails": true
}

Mode 3: DIRECT URLS MODE (Still Alive Checks)

When directUrls is provided, the scraper operates in direct mode:

  • Skips search phase - Goes directly to provided job URLs
  • Job status detection - Returns online, offline, expired, or unknown
  • Full data extraction - Same as detail page scraping
  • Use case: Periodic "still alive" checks, re-scraping specific jobs after deduplication
{
"directUrls": [
"https://www.linkedin.com/jobs/view/3812345678",
"https://www.linkedin.com/jobs/view/3823456789",
"https://www.linkedin.com/jobs/view/senior-software-engineer-at-google-3834567890"
]
}

Direct URLs mode workflow:

  1. Provide array of LinkedIn job URLs (must contain job ID)
  2. Scraper visits each URL directly
  3. Detects if job is still online or has been removed
  4. Extracts full job data if available
  5. Returns job_status field indicating availability

Filter Options

Date Posted

ValueDescription
anyAll jobs (default)
past-24hPosted in last 24 hours
past-weekPosted in last 7 days
past-monthPosted in last 30 days

Job Type

ValueDescription
full-timeFull-time positions
part-timePart-time positions
contractContract/freelance work
temporaryTemporary positions
internshipInternships

Experience Level

ValueDescription
entryEntry level / Junior
associateAssociate level
mid-seniorMid-Senior level
directorDirector level
executiveExecutive / C-level

Remote/On-site

ValueDescription
remoteFully remote positions
on-siteOn-site only
hybridHybrid work arrangements

Example Input

Basic Search (IT Jobs in Switzerland)

{
"searchQuery": "Software Engineer",
"location": "Switzerland",
"maxResults": 100
}

Recent Remote Jobs

{
"searchQuery": "Developer",
"remoteFilter": "remote",
"datePosted": "past-week",
"maxResults": 200
}

Senior Positions in Zurich

{
"searchQuery": "Manager",
"location": "Zurich",
"experienceLevel": "mid-senior",
"jobType": "full-time",
"maxResults": 50
}

Full Data Collection

{
"searchQuery": "Data Engineer",
"location": "Germany",
"maxResults": 100,
"includeJobDetails": true
}

Direct URLs - Still Alive Check

{
"directUrls": [
"https://www.linkedin.com/jobs/view/3812345678",
"https://www.linkedin.com/jobs/view/3823456789"
]
}

Output

Each job listing follows the standardized JobListing schema:

{
"id": "3812345678",
"title": "Senior Software Engineer",
"company": "Google",
"location": "Zurich, Switzerland",
"canton": "ZH",
"job_status": "online",
"top_listing": false,
"employment_type": "full-time",
"workload_min": null,
"workload_max": null,
"remote_option": "hybrid",
"salary_text": "CHF 150'000 - 200'000",
"description_snippet": "We're looking for a Senior Software Engineer to join our Zurich office...",
"description_full": "Full job description with all details...",
"requirements": [],
"posted_at": "2024-12-10T00:00:00.000Z",
"expires_at": null,
"source_url": "https://www.linkedin.com/jobs/view/3812345678",
"source_platform": "linkedin.com",
"apply_url": "https://careers.google.com/apply/12345",
"company_url": "https://www.linkedin.com/company/google",
"company_industry": "Technology, Information and Internet",
"company_employee_count": "10,001+ employees",
"scraped_at": "2024-12-13T10:30:00.000Z"
}

Output Fields

FieldDescription
idLinkedIn job ID (from URL)
titleJob title
companyCompany name
locationCity/location as displayed
cantonSwiss canton code (ZH, BE, etc.) - only for Swiss jobs
job_statusJob availability: online, offline, expired, unknown (Direct URLs mode only)
top_listingBoolean - if job is promoted/sponsored (Search mode only)
employment_typefull-time, part-time, contract, temporary, internship
workload_minMinimum workload percentage (usually null for LinkedIn)
workload_maxMaximum workload percentage (usually null for LinkedIn)
remote_optionremote, hybrid, onsite, or null
salary_textSalary as displayed (if available)
description_snippetFirst 500 characters of description
description_fullComplete job description (Details mode only)
requirementsArray of requirements (usually empty for LinkedIn)
posted_atPublication date
expires_atExpiration date (usually null)
source_urlLink to job posting on LinkedIn
source_platformAlways "linkedin.com"
apply_urlExternal application URL
company_urlLinkedIn company page URL
company_industryCompany industry/sector
company_employee_countCompany size (e.g., "501-1000 employees")
scraped_atTimestamp when job was scraped

Notes on job_status field:

  • Only populated in Direct URLs mode (Mode 3)
  • In Search modes (Mode 1 & 2), this field is null since jobs from search results are assumed to be online
  • Values:
    • online - Job page loaded successfully with content
    • offline - Job page returns "not found" or similar
    • expired - Job explicitly marked as expired or closed
    • unknown - Unable to determine status

Usage

Via Apify Console

  1. Go to the actor page
  2. Configure input parameters
  3. Click "Start"
  4. Download results from the Dataset tab (JSON, CSV, Excel)

Via API

curl -X POST "https://api.apify.com/v2/acts/santamaria~linkedin-scraper/runs" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"searchQuery": "Software Engineer",
"location": "Switzerland",
"maxResults": 100
}'

Via Apify SDK (Node.js)

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('santamaria/linkedin-scraper').call({
searchQuery: 'Data Scientist',
location: 'Zurich',
datePosted: 'past-week',
maxResults: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Found ${items.length} jobs`);

Still Alive Checks via API

// Check if previously scraped jobs are still online
const run = await client.actor('santamaria/linkedin-scraper').call({
directUrls: [
'https://www.linkedin.com/jobs/view/3812345678',
'https://www.linkedin.com/jobs/view/3823456789',
]
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach(job => {
console.log(`Job ${job.id}: ${job.job_status}`);
// Output: "Job 3812345678: online" or "Job 3823456789: offline"
});

Performance

  • Speed: ~50-100 jobs/minute (limited by respectful rate limiting)
  • Cost: ~0.02-0.05 CU per 100 jobs
  • Rate limiting: 2 seconds between search pages, 1 second between detail pages
  • Reliability: Built-in retry logic and error handling

Proxy Recommendations

LinkedIn has anti-bot protection. For best results:

  • Use Residential proxies (required)
  • Avoid Datacenter proxies (will be blocked)
  • Keep maxResults reasonable (<500 per run)
  • Add delays between runs if scraping frequently
{
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

Common Use Cases

  1. Job market analysis: Track hiring trends across industries and locations
  2. Competitive intelligence: Monitor which companies are hiring for specific roles
  3. Job aggregation: Build job search platforms with LinkedIn data
  4. Still-alive monitoring: Check if previously scraped jobs are still active (Direct URLs mode)
  5. Post-deduplication enrichment: Scrape basic data first, then fetch details for new jobs only
  6. Lead generation: Find companies that are actively hiring
  7. Recruitment analytics: Analyze job market data for specific roles
  8. Salary research: Analyze compensation ranges (when displayed)

How It Works

Search Mode (Modes 1 & 2)

  1. API Phase: Queries LinkedIn's public guest API for job search results
  2. Parsing: Extracts job data from API response (title, company, location, etc.)
  3. Detail Phase (optional): Visits each job's detail page with Playwright for full description
  4. Validation: Each job is validated against the JobListing schema before saving
  5. Pagination: Automatically follows pagination (25 jobs per page) until maxResults is reached

Direct URLs Mode (Mode 3)

  1. Skip search: Goes directly to provided job URLs
  2. Page load: Uses Playwright to render job detail pages
  3. Status detection: Checks if job page shows valid content or error
  4. Extraction: Extracts all available job data
  5. Status field: Returns job_status indicating availability

Notes

  • LinkedIn's page structure changes frequently; selectors may need updates
  • Some job details (salary, requirements) may not always be available
  • Rate limiting applies - don't run too many concurrent requests
  • No login required - uses publicly accessible job search
  • Job IDs are extracted from URLs (numeric format: 3812345678)
  • Swiss canton codes are automatically detected from location text

This actor scrapes publicly available job listings from LinkedIn's public job search (no login required). It does not access any data behind LinkedIn's authentication wall.

Users are responsible for ensuring their use complies with LinkedIn's Terms of Service and applicable laws in their jurisdiction.


Part of the Santamaria Job Scrapers Suite - Professional-grade job data for the DACH region and beyond.

Need help with integration, aggregation, or custom scraping solutions? Contact us at contact@alessandrosantamaria.com