Overview
LinkedIn is one of the largest professional networking platforms, hosting millions of job postings worldwide. JobSpy JS scrapes LinkedIn using HTML parsing of the public job search pages.LinkedIn aggressively rate-limits scrapers. For best results:
- Use residential proxies or clean IPs
- Enable credential fallback for authenticated access when blocked
- Keep
results_wantedmoderate (≤50 per run)
Scraping Method
HTML scraping oflinkedin.com/jobs-guest/jobs/api/seeMoreJobPostings/search
- Parses job cards from search result pages
- Extracts basic metadata (title, company, location, salary)
- Optionally fetches full job descriptions via separate requests
- Supports authenticated fallback when anonymous access is blocked (429 errors or auth walls)
Authentication & Credentials
LinkedIn may block anonymous scraping with 429 rate limits or redirect to auth walls. When this happens, JobSpy can automatically fall back to authenticated scraping if credentials are configured.Enable credential fallback
Environment variables
CLI usage
LinkedIn-Specific Parameters
linkedin_fetch_description
By default, LinkedIn search results include only basic job metadata. Set this to true to fetch full job descriptions (slower but more complete data).
false(default): Fast, but descriptions are emptytrue: Slower (1 extra request per job), but includes full job details, seniority level, employment type, industry, etc.
linkedin_company_ids
Filter results to specific companies using LinkedIn company IDs:
Visit a company’s LinkedIn page and extract the ID from the URL:
https://www.linkedin.com/company/1441/ → company ID is 1441
Example Usage
Basic search
Fetch full details for a single job
Filter by job type and recency
With credential fallback
Supported Filters
| Filter | Support | Notes |
|---|---|---|
search_term | ✅ | Job title or keywords |
location | ✅ | City, state, or region |
distance | ✅ | Radius in miles (default: 50) |
is_remote | ✅ | Remote-only filter |
job_type | ✅ | fulltime, parttime, contract, internship, temporary |
hours_old | ✅ | Filter by posting age |
easy_apply | ✅ | LinkedIn Easy Apply jobs only |
linkedin_company_ids | ✅ | Filter by specific companies |
Returned Fields
Whenlinkedin_fetch_description: false (default):
id,title,company_name,company_url,location,date_posted,job_url,compensation(if available),is_remote
linkedin_fetch_description: true:
- All of the above, plus:
description(full job description in markdown/HTML/plain)job_level(e.g., “entry level”, “mid-senior level”)job_type(e.g.,["fulltime"])company_industry(e.g., “Software Development”)job_function(e.g., “Engineering”)job_url_direct(direct application URL, if available)company_logoemails(extracted from description)
Rate Limits & Best Practices
Use proxies
Keep results_wanted moderate
LinkedIn typically allows ~10 pages (100 jobs) before blocking. Request fewer results per run:Add delays between runs
The scraper includes built-in delays (3-7 seconds between pages). For multiple consecutive runs, add manual delays:Use credential fallback for higher limits
Authenticated scraping (when enabled) can sometimes bypass anonymous rate limits:Troubleshooting
429 Rate Limit Error
Symptom:429 Response - Blocked by LinkedIn for too many requests
Solutions:
- Enable credential fallback with
use_creds: true - Use residential proxies
- Reduce
results_wanted - Add longer delays between runs
Auth-wall redirect
Symptom: Jobs return empty or redirect to signup page Solutions:- Enable credential fallback
- Use a different IP/proxy
- Clear cookies and retry
Empty descriptions
Symptom:description field is empty
Solution: Set linkedin_fetch_description: true to fetch full descriptions
CLI Examples
Source Code
- Implementation:
~/workspace/source/src/scrapers/linkedin/index.ts - Key:
linkedin - Site enum:
Site.LINKEDIN
