LinkedIn Job Scraper avatar

LinkedIn Job Scraper

Pricing

from $1.00 / 1,000 jobs

Go to Apify Store
LinkedIn Job Scraper

LinkedIn Job Scraper

LinkedIn job dataset from keywords or search URLs, including title, company, location, employment type, and optional company-page fields.

Pricing

from $1.00 / 1,000 jobs

Rating

0.0

(0)

Developer

Farhan Ali

Farhan Ali

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

8 hours ago

Last modified

Categories

Share

LinkedIn Job Scraper creates a structured dataset of job postings collected from LinkedIn. Each dataset item represents one LinkedIn job and can include identifiers, title, description, posting dates, employment type, company name and URL, location fields, coordinates, industry, skills, experience, and education. Query the source with keyword searches (searchQueries) plus locations and filters, or with LinkedIn job search URLs in startUrls (these override searchQueries when provided). Control the result limit with maxItems, and retrieve records through the Apify Dataset API or export them as JSON, CSV, Excel, XML, or another supported format.

Dataset at a glance

PropertyValue
Sourcelinkedin.com (public job listings)
Record unitOne LinkedIn job
Input methodsKeyword search (searchQueries) plus locations and filters, or LinkedIn job search URLs (startUrls)
Main identifiersjobId, url
DeliveryApify Dataset and API
Export formatsJSON, CSV, Excel, XML, HTML (Apify dataset exports)
Update modelFresh records per Actor run
Pricing$0.00005 per Actor start; $0.001 per job ($1 per 1,000 jobs)

Coverage and available records

The Actor collects public LinkedIn job listings using one of two entry points:

  • Search-based: Set searchQueries to job titles or keywords (for example Python Developer). Each query is a separate search. locations applies to every query. Filters (timeRange, jobType, experienceLevel, remote) narrow the search.
  • URL-based: Pass LinkedIn job search URLs in startUrls. When startUrls is provided, searchQueries is ignored.

Record types and limits:

  • Job records are always collected: jobId, title, description, dates, employment type, company name and URL, location fields, coordinates, industry, skills, experience, education, and the job URL.
  • Company page fields are conditional: they attach onto the same job record only when extractCompanyDetails is enabled. They are not a separate dataset item.
  • Result cap: maxItems limits the number of jobs collected (0 means unlimited, the default; Console prefill is 10).

Known exclusions: content LinkedIn only shows behind login is not collected; each run captures listing state at run time (no historical snapshots); company page fields are omitted when extractCompanyDetails is off or the company page is unavailable.

Data dictionary

Field names below match dataset record JSON properties exactly. jobId is the recommended deduplication key; url is a reasonable secondary key. Dates are ISO 8601 timestamps as returned on the listing (for example 2026-05-08T13:38:46.000Z). country is a country code. latitude and longitude are decimal degrees when present.

FieldTypeNullableDescriptionExample
jobIdstringNoLinkedIn job identifier; best stable deduplication key4412111373
titlestringNoJob titlePython Developer
descriptionstringYesFull job description textSee example record
datePostedstringYesPosting timestamp (ISO 8601)2026-05-08T13:38:46.000Z
validThroughstringYesListing end timestamp (ISO 8601)2026-11-04T13:38:46.000Z
employmentTypestringYesEmployment type as shown on the listingFULL_TIME
companyNamestringYesHiring company nameDATAGROUP
companyUrlstringYesLinkedIn company page URLhttps://de.linkedin.com/company/datagroup-se
companyLogostringYesCompany logo image URLSee example record
countrystringYesCountry codeDE
citystringYesCity as shown on the listingKrakau
latitudenumberYesLocation latitude in decimal degrees51.36391
longitudenumberYesLocation longitude in decimal degrees11.857489
industrystringYesIndustry text as shown on the listingIT-Dienstleistungen und IT-Beratung
skillsstringYesSkills text; empty when the listing does not provide it""
monthsOfExperiencestringYesExperience requirement as returned on the listing; empty when not provided""
educationLevelstringYesEducation requirement as shown on the listingbachelor degree
urlstringNoJob posting URL; secondary deduplication keyhttps://de.linkedin.com/jobs/view/python-developer-at-datagroup-4412111373
locationstringYesFull location string (city, region, country)Krakau, Saxony-Anhalt, Germany

When extractCompanyDetails is true, company page fields attach onto this same job record. They are omitted when the toggle is off.

Example dataset record

Real record produced with the test input below (searchQueries: Python Developer, locations: Germany, maxItems: 10). The description text is shortened for readability; the live record contains the full listing copy.

{
"jobId": "4412111373",
"title": "Python Developer",
"description": "Job Description DATAGROUP Polska. Design and implement robust, scalable, and efficient JAVA-based frontend as well as Python components for the ETL process.",
"datePosted": "2026-05-08T13:38:46.000Z",
"validThrough": "2026-11-04T13:38:46.000Z",
"employmentType": "FULL_TIME",
"companyName": "DATAGROUP",
"companyUrl": "https://de.linkedin.com/company/datagroup-se",
"companyLogo": "https://media.licdn.com/dms/image/v2/C4D0BAQFCZT1emBoUsw/company-logo_200_200/company-logo_200_200/0/1630477221838/datagroup_ag_logo?e=2147483647&v=beta&t=kHRk6yObQhtWun4zVyZKfRI6iNwfH5xZ2aTfFnDTOjQ",
"country": "DE",
"city": "Krakau",
"latitude": 51.36391,
"longitude": 11.857489,
"industry": "IT-Dienstleistungen und IT-Beratung",
"skills": "",
"monthsOfExperience": "",
"educationLevel": "bachelor degree",
"url": "https://de.linkedin.com/jobs/view/python-developer-at-datagroup-4412111373",
"location": "Krakau, Saxony-Anhalt, Germany"
}

The record above was produced with this input:

{
"searchQueries": ["Python Developer"],
"locations": ["Germany"],
"timeRange": "any",
"maxItems": 10,
"extractCompanyDetails": false,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

Query and input reference

InputTypeRequiredDefaultAccepted valuesDescription
searchQueriesarrayNo*[]Free-text keywords (prefill Python Developer)Job titles or keywords. Each value is a separate search. Ignored when startUrls is provided
startUrlsarray (requestListSources)No*[]LinkedIn job search URLsURL-based entry point. Overrides searchQueries when provided
locationsarrayNo[]Free-text locations (e.g. Germany, London)Location filter applied to every search query
timeRangestringNoanyany, past24Hours, pastWeek, pastMonthFilter jobs by posting date
jobTypearrayNo[]fullTime, partTime, contract, temporary, internship, volunteerEmployment-type filter; empty means all types
experienceLevelarrayNo[]internship, entryLevel, associate, midSenior, director, executiveExperience-level filter; empty means all levels
remotearrayNo[]onSite, remote, hybridWork-arrangement filter; empty means all types
maxItemsintegerNo00 or any positive integerMaximum jobs to collect; 0 = unlimited (Console prefill 10)
extractCompanyDetailsbooleanNofalsetrue / falseAttach company page fields onto each job record
maxConcurrencyintegerNo5120Maximum parallel detail-page fetches
proxyConfigurationobjectNoApify proxy, RESIDENTIAL groupApify proxy groups or custom proxiesResidential proxies are recommended

* Provide searchQueries or startUrls — at least one source is required to collect records.

Minimal request:

{ "searchQueries": ["Python Developer"], "locations": ["Germany"] }

Advanced request (filters plus company page fields):

{
"searchQueries": ["Python Developer"],
"locations": ["Germany"],
"timeRange": "pastWeek",
"jobType": ["fullTime"],
"experienceLevel": ["midSenior"],
"remote": ["remote", "hybrid"],
"maxItems": 500,
"extractCompanyDetails": true,
"maxConcurrency": 5,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}

Retrieve the data through the API

The Actor runs on the Apify platform, so there is no server to host and no crawling infrastructure to maintain.

  1. Start the Actor with a JSON input (console or API).
  2. Wait for the run to finish, or use a synchronous endpoint if you want the response inline.
  3. Retrieve items from the run's default dataset.
  4. Paginate or export the dataset.

Python example:

from apify_client import ApifyClient
client = ApifyClient("YOUR-APIFY-TOKEN")
run_input = {
"searchQueries": ["Python Developer"],
"locations": ["Germany"],
"maxItems": 10,
}
run = client.actor("datascrapers/linkedin-job-scraper").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["jobId"], item["title"], item["companyName"])

Apify generates ready-to-run Python, JavaScript, and cURL examples on the Actor's API tab. Do not put a real API token in shared code or URLs.

Data quality and record handling

  • Conditional fields: company page fields are present only when extractCompanyDetails is enabled. Listings alone return the job fields in the data dictionary.
  • Source changes: LinkedIn page structure and values can change; fields the listing does not provide are returned as empty values rather than fabricated.
  • Deduplication: within a run, repeated jobId values are skipped. Across runs, the Actor does not deduplicate. Use jobId as the stable key, or url as a secondary key, and filter repeated runs against previously stored identifiers.
  • Empty source values: skills and monthsOfExperience are often empty strings when the listing does not publish them. latitude and longitude are omitted or empty when coordinates are not present.
  • Normalization: dates are stored as ISO 8601 strings; country is a country code; employmentType uses the listing value (for example FULL_TIME). Values are read from the listing and mapped to the field types in the data dictionary.

Export and pipeline examples

DestinationRecommended methodTypical use
PostgreSQL / SupabaseDataset API poll or webhook consumerStore job rows for labor-market or recruiting analysis
Google SheetsApify Google Sheets integrationShare shortlists with recruiting or research teams
ATS / CRMWebhook on run completionPush new jobs into sourcing pipelines
S3 / cloud storageScheduled export via Apify scheduler + integrationArchival of hiring-market snapshots

Pricing and cost examples

The Actor uses pay-per-event pricing. Live charges are:

EventTriggerRate
Actor startOnce per run$0.00005
Job result (apify-default-dataset-item)Every job record written to the default dataset$0.001 ($1 per 1,000 jobs)

extractCompanyDetails attaches company page fields onto the same job record. It is not a separate billed event.

Example costs:

RecordsConfigurationEstimated base cost
1,000Jobs only$1.00005
10,000Jobs only$10.00005
1,000Jobs + company page fields$1.00005
10,000Jobs + company page fields$10.00005

Compute units and proxy traffic consumed by the run are billed by your Apify plan. Estimates depend on the verified pricing model and the options selected for the run.

Limitations and responsible data use

  • The Actor collects publicly accessible data from LinkedIn job pages only.
  • Field availability depends on what LinkedIn renders at run time; some values can be empty or missing, and site changes can alter fields.
  • Company page fields attach onto job records; they are not standalone dataset items.
  • The Actor does not provide historical snapshots unless you store them yourself.
  • Residential proxies are recommended; coverage may degrade without them.
  • You are responsible for compliance with LinkedIn's terms of service, applicable privacy law, and any contractual obligations before using the data.

Dataset questions

What does one dataset item represent?

One LinkedIn job. Company page fields attach onto that same row when extractCompanyDetails is enabled. Enabling company details does not create extra dataset items.

Which field should I use as a unique identifier?

jobId is the LinkedIn job identifier and is the recommended deduplication key. url is a reasonable secondary key.

Are fields nullable or conditional?

Yes. Company page fields exist only when extractCompanyDetails is enabled. Within job records, fields the listing does not publish (commonly skills and monthsOfExperience) are returned as empty values.

Do startUrls override searchQueries?

Yes. When startUrls contains LinkedIn job search URLs, those URLs are used and searchQueries is ignored. Use searchQueries plus locations and filters when you want keyword search.

Can I retrieve the records as CSV or JSON?

Yes. The dataset can be exported as JSON, CSV, Excel, XML, or HTML from the Apify Console, and queried through the Dataset API.

Does the Actor return historical data?

No. Each run captures the state of the listings at run time. To track hiring changes over time, schedule repeated runs and store the outputs yourself.

What counts as a billable result?

Two charges apply: $0.00005 once per Actor start, and $0.001 for every job record written to the default dataset ($1 per 1,000 jobs). Company page fields do not add a billed event.

  • Dice.com Job Scraper — Technology job listings that can be compared with LinkedIn jobs by title, company, and skills.
  • Naukri Job Scraper — India job listings that can be joined with LinkedIn rows by title and company for cross-board coverage.
  • Glassdoor Jobs Scraper — Job listings with employer ratings that can be joined to LinkedIn jobs by company name and title.
  • ZipRecruiter Job Scraper — US job listings for labor-market comparison against LinkedIn roles.
  • LinkedIn Company Scraper — Company profiles that can be joined with these job records by company name or companyUrl.
  • LinkedIn Profile Scraper — Public profile records for hiring-team or candidate research alongside job listings.

Data Scrapers support

Need an additional field, record type, or export workflow? Contact Data Scrapers at stardustspotlight@gmail.com. Include a sample source URL, required fields, expected record volume, and preferred delivery format.