# Glassdoor Jobs Scraper (`captainhandsome/glassdoor-jobs-scraper`) Actor

Scrape Glassdoor job listings: job title, employer, company rating, location and salary range as structured JSON or CSV.

- **URL**: https://apify.com/captainhandsome/glassdoor-jobs-scraper.md
- **Developed by:** [Joseph McRell](https://apify.com/captainhandsome) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Glassdoor Jobs Scraper - URLs, Dates, Salaries & Employers

Extract public Glassdoor job-search cards into structured, CSV-ready records with canonical job URLs, stable Glassdoor job IDs, posting age, an explicitly qualified posting-date estimate, job title, employer, company rating, location, and displayed salary. Supply one or more Glassdoor search-result URLs and set a hard result ceiling for predictable Store or AI-agent calls.

### What data can I extract?

- Job title
- Canonical Glassdoor job URL with tracking parameters removed
- Stable Glassdoor job ID
- Employer name and rating when displayed
- Job location
- Displayed salary range or estimate
- Source posting-age text such as `24h`, `3d`, or `30d+`
- Estimated posting date plus a precision label
- UTC scrape timestamp

### Input example

```json
{
  "start_urls": [
    {
      "url": "https://www.glassdoor.com/Job/austin-tx-developer-jobs-SRCH_IL.0,9_IC1139761_KO10,19.htm"
    }
  ],
  "max_items": 30
}
```

You can supply up to 25 public Glassdoor search-result URLs. `max_items` is a hard run-wide output ceiling.

### Output example

```json
{
  "job_title": "Senior Embedded Software Engineer",
  "job_url": "https://www.glassdoor.com/job-listing/senior-embedded-software-engineer-example-JV_IC1139794_KO0,33_KE34,41.htm?jl=1010258975267",
  "job_id": "1010258975267",
  "employer": "Example Technologies",
  "rating": "4.4",
  "location": "Round Rock, TX",
  "salary": "$119K - $164K (Glassdoor est.)",
  "posting_age": "3d",
  "posting_date_estimated": "2026-09-07",
  "posting_date_precision": "estimated",
  "scraped_at": "2026-09-10T16:50:22Z"
}
```

`posting_date_estimated` is derived from Glassdoor's relative age label; it is not represented as an exact source-supplied date. A `30d+` value is labeled `lower_bound` because the job may be older than 30 days.

### Common use cases

- Open or deduplicate jobs using canonical URLs and stable IDs
- Compare displayed salary ranges by role and market
- Monitor posting age across public job-search result pages
- Build a bounded list of hiring employers
- Supply fresh, linkable job-card context to an AI agent

### Use with AI agents and MCP

Example agent intent:

> Extract the first 30 Glassdoor software developer jobs from this Austin search URL and return canonical links, job IDs, posting age, estimated dates, employers, ratings, locations, and salaries.

```json
{
  "start_urls": [
    {
      "url": "https://www.glassdoor.com/Job/austin-tx-developer-jobs-SRCH_IL.0,9_IC1139761_KO10,19.htm"
    }
  ],
  "max_items": 30
}
```

### Pricing and cost control

The current launch price is **$0.004 per result**. Output charges are approximately $0.40 for 100 jobs or $4.00 for 1,000, plus the Actor-start or platform charges shown by Apify. The live Store pricing is authoritative. Use `max_items` to cap output.

### Reliability

The Actor renders Glassdoor search pages, deduplicates on canonical job URL, validates stable job-card anchors, and is enrolled in staged selector monitoring and self-healing. Repairs are tested against multiple pages and output contracts before promotion.

### Limitations and responsible use

- Public search-card fields only; this version does not promise full descriptions or external employer application URLs.
- Posting dates are transparent estimates derived from relative age labels. `30d+` is a lower bound, not an exact date.
- Salary is source display text and can contain estimates or employer-provided labels.
- Some cards omit rating or salary.
- Availability varies by geography and upstream access policy.
- You are responsible for complying with applicable law, Glassdoor terms, and restrictions on employment-data use.

### FAQ

#### Does every result include a usable job link?

Yes. The publication contract requires a canonical HTTPS Glassdoor job URL and numeric `job_id` for every emitted record.

#### Are posting dates exact?

No. Glassdoor search cards expose relative age. The Actor preserves that value in `posting_age`, derives a best-effort date, and states whether it is an estimate or lower bound.

#### Can I scrape Glassdoor salary ranges?

Yes, when a salary or estimate is displayed on the public result card. It is returned in `salary` without pretending it is normalized compensation data.

#### Can I search by keyword and city directly?

This version accepts Glassdoor search-result URLs. That preserves exact filters selected on Glassdoor and avoids an ambiguous query-to-URL translation.

See [CHANGELOG.md](CHANGELOG.md) for maintained schema changes.

# Actor input Schema

## `start_urls` (type: `array`):

One or more public Glassdoor job-search result URLs to scrape.

## `max_items` (type: `integer`):

Hard maximum number of unique job records returned and billed.

## Actor input object example

```json
{
  "start_urls": [
    {
      "url": "https://www.glassdoor.com/Job/austin-tx-developer-jobs-SRCH_IL.0,9_IC1139761_KO10,19.htm"
    }
  ],
  "max_items": 30
}
```

# Actor output Schema

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

Extracted records, one object per row on the source page.

# 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 = {
    "start_urls": [
        {
            "url": "https://www.glassdoor.com/Job/austin-tx-developer-jobs-SRCH_IL.0,9_IC1139761_KO10,19.htm"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("captainhandsome/glassdoor-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 = { "start_urls": [{ "url": "https://www.glassdoor.com/Job/austin-tx-developer-jobs-SRCH_IL.0,9_IC1139761_KO10,19.htm" }] }

# Run the Actor and wait for it to finish
run = client.actor("captainhandsome/glassdoor-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 '{
  "start_urls": [
    {
      "url": "https://www.glassdoor.com/Job/austin-tx-developer-jobs-SRCH_IL.0,9_IC1139761_KO10,19.htm"
    }
  ]
}' |
apify call captainhandsome/glassdoor-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,captainhandsome/glassdoor-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/O3bGntkL3IGd7pVrZ/builds/MgMelmhvNfFj2GJpy/openapi.json
