# Fast & Low-Cost LinkedIn Jobs Scraper (`ahmed_abdelsalam/fast-linkedin-jobs-scraper`) Actor

Ultra-fast, lightweight LinkedIn job scraper built with Python and Crawlee. Extracts job titles, companies, locations, and direct URLs without requiring logins or browser automation.

- **URL**: https://apify.com/ahmed\_abdelsalam/fast-linkedin-jobs-scraper.md
- **Developed by:** [Ahmed Elowny](https://apify.com/ahmed_abdelsalam) (community)
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## LinkedIn Jobs Scraper: Fast, No Login

> **v1.1.0 Beta** — This release adds Apify Proxy support (cloud-only) and enforces a URL cap based on the session pool capacity. It is not the default build; deploy with `apify push` and select the `beta` tag to test it.

### What does LinkedIn Jobs Scraper do?

**LinkedIn Jobs Scraper** extracts structured job listings from [LinkedIn Jobs](https://www.linkedin.com/jobs/) — no login, no browser, no cookies required. Paste any LinkedIn job search URL and the scraper returns job titles, companies, locations, posting dates, and direct job links in seconds.

Enable the **Scrape Job Details** option to unlock richer data: full job descriptions, seniority levels, contract types, work arrangements (Remote / Hybrid / On-site), salary ranges, applicant counts, recruiter profiles, and direct apply links.

The Actor uses LinkedIn's public guest API endpoints and HTTP parsing — making it roughly **10× faster and cheaper** to run than browser-based scrapers. Schedule it on the [Apify platform](https://apify.com) with proxy rotation, automatic retries, and easy export to JSON, CSV, or Excel.

***

### Why use LinkedIn Jobs Scraper?

- **Talent intelligence** — track which companies are actively hiring for specific roles, technologies, or locations
- **Job market research** — monitor salary trends, demand spikes, and emerging skill requirements across industries
- **Competitive hiring analysis** — see how your competitors are growing their teams
- **Automated job alerts** — run on a schedule to get notified about fresh postings the moment they appear
- **ATS and workflow integration** — feed structured job data directly into spreadsheets, databases, or recruiting tools via the Apify API
- **Career research** — build a comprehensive picture of the market before a job search or salary negotiation

***

### How to use LinkedIn Jobs Scraper

1. **Open the Actor** on the Apify platform and click **Try for free**
2. **Paste a LinkedIn Jobs search URL** in the *Start URLs* field\
   Example: `https://www.linkedin.com/jobs/search/?keywords=Python+Developer&location=London`
3. *(Optional)* Toggle **Scrape Job Details** to `true` for full descriptions and extra fields
4. *(Optional)* Add **Exclude Keywords** to skip titles like "Senior", "Lead", or "Manager"
5. Set a **Maximum Jobs** limit (default: 25)
6. Click **Start** and wait a few seconds
7. Download results from the **Output** tab in JSON, CSV, or Excel

> **Tip:** Build any search URL you like on LinkedIn — by keyword, location, date posted, experience level, or company — and paste it directly into the Actor.

***

### Input

Configure the Actor from the **Input** tab or by passing a JSON payload to the API.

| Field                | Type    | Required | Default                                                              | Description                                                                                           |
| -------------------- | ------- | -------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `startUrls`          | array   | ✅       | `[{"url": "https://www.linkedin.com/jobs/search/?keywords=Python"}]` | One or more LinkedIn job search URLs. **Maximum 64 URLs per run** (see URL limit section below)       |
| `scrapeDetails`      | boolean | ❌       | `false`                                                              | Open each job page for full details                                                                   |
| `jobTitleExclude`    | array   | ❌       | `[]`                                                                 | Skip jobs with these keywords in the title                                                            |
| `maxItems`           | integer | ❌       | `25`                                                                 | Maximum unique jobs to collect (up to 640)                                                            |
| `proxyConfiguration` | object  | ❌       | `{ "useApifyProxy": true, "apifyProxyGroups": ["DATACENTER"] }`      | Proxy settings. **Active on Apify platform only** — ignored during local `apify run` (see note below) |

**Example input (JSON):**

```json
{
  "startUrls": [
    {
      "url": "https://www.linkedin.com/jobs/search/?keywords=Backend+Engineer&location=Germany&f_TPR=r86400"
    }
  ],
  "scrapeDetails": true,
  "jobTitleExclude": ["Staff", "Principal"],
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["DATACENTER"]
  }
}
```

#### URL limit

The number of start URLs you can process in a single run depends directly on the proxies available. Each proxy has a limited request budget, so the more proxies your plan provides, the more search URLs you can handle in one run.

To scrape more searches than your proxy budget allows, split them across multiple runs.

#### Proxy note

`proxyConfiguration` is **only active when the Actor runs on the Apify platform**. During local development (`apify run`), the proxy is skipped automatically — no configuration change is needed to switch between environments.

***

### Output

Results are stored in the **default dataset** and are accessible in real time from the **Output** tab. You can download the dataset in various formats such as **JSON, HTML, CSV, or Excel**.

#### Fast mode (`scrapeDetails: false`) — sample output

```json
{
  "id": "4473763235",
  "title": "Backend Engineer",
  "companyName": "Acme Corp",
  "companyUrl": "https://www.linkedin.com/company/acme-corp",
  "location": "Berlin, Germany",
  "publishedAt": "2026-09-30",
  "postedTime": "2 hours ago",
  "benefits": "Be an early applicant",
  "jobUrl": "https://www.linkedin.com/jobs/view/backend-engineer-at-acme-corp-4473763235",
  "scrapingInfo": {
    "page": 1,
    "index": 3,
    "inputUrl": "https://www.linkedin.com/jobs/search/?keywords=Backend+Engineer&location=Germany"
  }
}
```

#### Full details mode (`scrapeDetails: true`) — sample output

```json
{
  "id": "4473763235",
  "title": "Backend Engineer",
  "companyName": "Acme Corp",
  "companyUrl": "https://www.linkedin.com/company/acme-corp",
  "location": "Berlin, Germany",
  "jobFunction": "Engineering",
  "contractType": "Full-time",
  "experienceLevel": "Mid-Senior level",
  "workType": "Hybrid",
  "salary": "$90,000 - $120,000/yr",
  "applyType": "EASY_APPLY",
  "applyUrl": "https://www.linkedin.com/jobs/view/...",
  "postedTime": "2 hours ago",
  "publishedAt": "2026-09-30",
  "applicationsCount": "47 applicants",
  "benefits": "Be an early applicant",
  "posterFullName": "Jane Smith",
  "posterProfileUrl": "https://www.linkedin.com/in/jane-smith",
  "jobUrl": "https://www.linkedin.com/jobs/view/backend-engineer-at-acme-corp-4473763235",
  "description": "We are looking for a backend engineer to join our platform team...",
  "scrapingInfo": {
    "page": 1,
    "index": 3,
    "inputUrl": "https://www.linkedin.com/jobs/search/?keywords=Backend+Engineer&location=Germany"
  }
}
```

***

### Data fields

| Field               | Mode    | Description                                                  |
| ------------------- | ------- | ------------------------------------------------------------ |
| `id`                | Both    | LinkedIn numeric job ID                                      |
| `title`             | Both    | Job title                                                    |
| `companyName`       | Both    | Hiring company name                                          |
| `companyUrl`        | Both    | Company LinkedIn page URL                                    |
| `location`          | Both    | Job location string                                          |
| `publishedAt`       | Both    | ISO date the job was posted (e.g. `2026-09-30`)              |
| `postedTime`        | Both    | Relative posting time (e.g. `"2 hours ago"`)                 |
| `benefits`          | Both    | Badge text (e.g. `"Be an early applicant"`)                  |
| `jobUrl`            | Both    | Direct link to the job posting                               |
| `scrapingInfo`      | Both    | Internal metadata: page, index, and source URL               |
| `jobFunction`       | Details | Job function category (e.g. `"Engineering"`)                 |
| `contractType`      | Details | Employment type (e.g. `"Full-time"`, `"Contract"`)           |
| `experienceLevel`   | Details | Seniority level (e.g. `"Entry level"`, `"Mid-Senior level"`) |
| `workType`          | Details | Work arrangement: `"Remote"`, `"Hybrid"`, or `"On-site"`     |
| `salary`            | Details | Salary range if listed by the employer                       |
| `applyType`         | Details | `"EASY_APPLY"` or `"EXTERNAL"`                               |
| `applyUrl`          | Details | Direct application URL                                       |
| `applicationsCount` | Details | Number of applicants shown on the page                       |
| `posterFullName`    | Details | Recruiter or poster display name                             |
| `posterProfileUrl`  | Details | Recruiter LinkedIn profile URL                               |
| `description`       | Details | Full plain-text job description                              |

***

### Pricing / Cost estimation

The Actor runs on Apify's **pay-per-event** billing model. Costs depend on the number of pages crawled and whether detail pages are enabled.

| Mode             | Requests per 100 jobs | Notes                                    |
| ---------------- | --------------------- | ---------------------------------------- |
| Fast (card only) | ~4–5 pages            | Very cheap — one API call per 25 results |
| Full details     | ~100–105 pages        | One extra request per job                |

**Rough estimates:**

- Scraping 100 jobs in fast mode typically costs less than **$0.01**
- Scraping 100 jobs with full details costs roughly **$0.05–$0.10** depending on proxy usage

New Apify accounts include a **free tier** that covers substantial usage. See the [Apify pricing page](https://apify.com/pricing) for current limits and paid plan details.

***

### Tips and advanced options

**Filter jobs to the last 24 hours**\
Add `f_TPR=r86400` to your search URL. For the past hour, use `f_TPR=r3600`. LinkedIn supports multiple time values that you can set in the LinkedIn search UI and copy the URL.

**Scrape multiple search URLs in one run**\
Add multiple objects to `startUrls` — the Actor deduplicates jobs across all of them, so you won't get duplicates even if the same job appears in multiple searches.

**Keep costs low with fast mode + keyword filter**\
Use `scrapeDetails: false` with `jobTitleExclude` to quickly harvest thousands of job cards, then re-run with `scrapeDetails: true` only on the specific roles you care about.

**Schedule for real-time alerts**\
Set the Actor to run on a 1-hour schedule with `f_TPR=r3600` in the URL and a low `maxItems` (e.g. 25). Connect the output to a webhook or Apify integration (Slack, email, Google Sheets) to get instant notifications on new listings.

**Use Apify Proxy for reliability**\
LinkedIn rate-limits unauthenticated requests aggressively. When running on the Apify platform, `proxyConfiguration.useApifyProxy: true` (the default) routes each request through a different datacenter IP, significantly reducing failures and retries. The proxy is automatically skipped during local development.

***

### FAQ, disclaimers, and support

**Is scraping LinkedIn legal?**\
The Actor only accesses publicly available, non-authenticated LinkedIn job listings — the same data visible to any anonymous visitor. The legal landscape for web scraping public data varies by jurisdiction. Always review LinkedIn's [Terms of Service](https://www.linkedin.com/legal/user-agreement) and consult your legal team before large-scale or commercial use.

**Why are some fields empty?**\
Not all jobs display every field. Salary, for example, is only listed by employers who opt in. Fields will be empty strings when the data is not present on the page.

**Can it scrape private or behind-login content?**\
No. The Actor uses LinkedIn's public guest API and does not support authenticated sessions or scraping of member-only content.

**The Actor returned fewer jobs than expected — why?**\
LinkedIn limits guest API access to a certain number of results per search (typically up to a few hundred per query). Narrow your search with more specific keywords, location filters, or date filters to get the most relevant results within those limits.

**Known limitations:**

- No authentication / login support
- LinkedIn may rate-limit or block requests in high-volume runs — use proxies and keep concurrency reasonable
- Job counts displayed on LinkedIn's UI are approximate and not always reachable via the guest API

**Need help or a custom solution?**\
Open an issue in the [Issues tab](https://console.apify.com/actors/fast-linkedin-jobs-scraper/issues) on Apify. For custom scraping solutions, data pipelines, or integrations, contact us through the Apify platform.

***

### About the author

Built by **Ahmed Abdelsalam** — Full-Stack & Backend Engineer with 5+ years of experience building scalable web architectures, high-performance APIs, and cloud infrastructure.

🌐 [ahmedabdelsalam.dev](https://ahmedabdelsalam.dev/)

# Actor input Schema

## `startUrls` (type: `array`):

Target LinkedIn search URLs (e.g. https://www.linkedin.com/jobs/search/?keywords=Python). The number of URLs you can run in a single session depends on the proxies available in your plan.

## `scrapeDetails` (type: `boolean`):

When enabled, opens every job page to extract description, experience level, contract type, job function, salary, apply type, applicants count and poster. Slower and more likely to hit rate limits. When disabled, only the search card data is returned.

## `jobTitleExclude` (type: `array`):

Skip jobs containing any of these keywords in their title.

## `maxItems` (type: `integer`):

Maximum number of unique job listings to extract across all input URLs.

## `proxyConfiguration` (type: `object`):

Proxy settings used when running on the Apify platform. Automatically configured to use Apify Proxy with the maximum available IPs.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.linkedin.com/jobs/search/?keywords=Python"
    }
  ],
  "scrapeDetails": false,
  "jobTitleExclude": [],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Direct link to all extracted job listings in JSON/CSV format.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.linkedin.com/jobs/search/?keywords=Python"
        }
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_abdelsalam/fast-linkedin-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.linkedin.com/jobs/search/?keywords=Python" }],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_abdelsalam/fast-linkedin-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.linkedin.com/jobs/search/?keywords=Python"
    }
  ],
  "maxItems": 20
}' |
apify call ahmed_abdelsalam/fast-linkedin-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_abdelsalam/fast-linkedin-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eO9dIKBu1DPaRBfVo/builds/syrxcZTyVGCmY6duf/openapi.json
