# Google Jobs Scraper (`searchapi/google-jobs-scraper`) Actor

Scrapes Google Jobs for any job title/location. Extracts job title, company, location, workplace/employment type, salary, description, posted/expires dates, apply URL, and more.

- **URL**: https://apify.com/searchapi/google-jobs-scraper.md
- **Developed by:** [Search API](https://apify.com/searchapi) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 14 total users, 6 monthly users, 1.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 search results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## 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

## Google Jobs Scraper

Search Google Jobs by job title and location, then collect normalized listing cards and expanded job details. The Actor opens Google's Jobs search surface, loads additional cards up to the configured limit, and expands each available job detail panel. If Google challenges the run network, it discovers indexed employer/job-board pages and emits records only when the source page publishes valid `JobPosting` JSON-LD.

### Input

| Field | Required | Default | Description |
| --- | --- | --- | --- |
| `query` | Yes | `software engineer` | Job title or keywords entered in Google Jobs. |
| `location` | No | `New York, NY` | City, state, region, or country included in the search. |
| `queries` | No | `[]` | Additional job queries. Native Google pages are processed concurrently and output is deduplicated globally. |
| `maxItems` | No | `50` | Maximum unique job records. |
| `maxConcurrency` | No | `2` | Concurrent search pages, from 1 to 4. |
| `gl` | No | `us` | Two-letter Google country code. |
| `hl` | No | `en` | Google interface language. |
| `experienceLevel`, `salaryMin`, `salaryMax`, `remoteFilter`, `educationLevel` | No | — | Retained for Cloud input compatibility and recorded in `requestedFilters` when supplied. The local Actor does not apply these criteria to result matching yet. |
| `maxScrolls` | No | `10` | Maximum result-list loads. |
| `maxRequestRetries` | No | `3` | Bounded retries for temporary failures and blocks. |
| `navigationTimeoutSecs` | No | `60` | Navigation timeout. |
| `requestHandlerTimeoutSecs` | No | `300` | Whole search-page handler timeout. |
| `detailTimeoutSecs` | No | `12` | Timeout while opening one job's detail panel. |
| `proxyConfiguration` | No | Google SERP proxy | Apify Proxy or custom proxy configuration. |

### Output

Records contain the fields Google exposes for each job when available:

- identity: stable `id`, `jobId`, result type, global position, title, company, and company logo;
- source provenance: `dataSource`, `retrievalMethod`, page number and result position for native Google Jobs cards, plus index provenance when the structured source-page fallback is used;
- location: location, city, state/region, country, remote/workplace type;
- employment and compensation: employment types, salary range, currency, period;
- job content: full description, qualifications, responsibilities, detailed benefits, card benefit highlights;
- dates and source: posted time, source board, source domain;
- application: primary apply URL and all available apply links;
- search context: query, requested location, locale, Google Jobs URL, requested filter values when supplied, and scrape timestamp.

Unavailable optional fields are omitted recursively. The Actor does not invent values from the search input, does not store challenge pages, and does not store raw Google responses.
Every emitted record includes at least 20 populated top-level fields, with source-backed listing values and search or retrieval metadata.

### Local validation

```sh
npm install
npm test
npm run validate:dataset
apify run --purge
```

Google commonly blocks datacenter IPs. Use an authorized Apify proxy configuration. CAPTCHA, authentication, or explicit access-control pages are reported as failures and are never stored as dataset records.

The source-page fallback is deliberately strict: it follows public indexed job URLs but emits a record only after validating a `JobPosting` JSON-LD object with a title, company, description, and canonical application URL. It does not bypass CAPTCHA or access controls.

# Changelog

This Actor's version history is a separate document: https://apify.com/searchapi/google-jobs-scraper/changelog.md

# Actor input Schema

## `query` (type: `string`):

Job title or keywords to enter in Google Jobs.

## `location` (type: `string`):

City, state, region, or country to include in the search.

## `queries` (type: `array`):

Optional additional keywords processed after the primary query.

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

Stop after this many unique jobs.

## `maxConcurrency` (type: `integer`):

Maximum number of query pages processed in parallel. Keep this low to reduce Google blocking.

## `gl` (type: `string`):

Two-letter country code used to localize Google results.

## `hl` (type: `string`):

Language code used for the Google Jobs interface.

## `experienceLevel` (type: `string`):

Retained for Cloud input compatibility and recorded in requestedFilters; the local Actor does not apply it to result matching.

## `salaryMin` (type: `number`):

Retained for Cloud input compatibility and recorded in requestedFilters; the local Actor does not apply it to result matching.

## `salaryMax` (type: `number`):

Retained for Cloud input compatibility and recorded in requestedFilters; the local Actor does not apply it to result matching.

## `remoteFilter` (type: `string`):

Retained for Cloud input compatibility and recorded in requestedFilters; the local Actor does not apply it to result matching.

## `educationLevel` (type: `string`):

Retained for Cloud input compatibility and recorded in requestedFilters; the local Actor does not apply it to result matching.

## `maxScrolls` (type: `integer`):

Maximum number of result-list scrolls used to load more jobs.

## `maxRequestRetries` (type: `integer`):

Retry temporary navigation, proxy, and block failures up to this many times.

## `navigationTimeoutSecs` (type: `integer`):

Maximum time allowed for the Google Jobs page navigation.

## `requestHandlerTimeoutSecs` (type: `integer`):

Maximum time allowed to load, expand, and extract one search page.

## `detailTimeoutSecs` (type: `integer`):

Maximum time allowed for an individual job detail panel to open.

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

Apify Proxy or custom proxy configuration. Residential or Google SERP access is recommended for Google Jobs.

## Actor input object example

```json
{
  "query": "software engineer",
  "location": "New York, NY",
  "maxItems": 50,
  "maxConcurrency": 2,
  "gl": "us",
  "hl": "en",
  "experienceLevel": "",
  "remoteFilter": "",
  "educationLevel": "",
  "maxScrolls": 10,
  "maxRequestRetries": 3,
  "navigationTimeoutSecs": 60,
  "requestHandlerTimeoutSecs": 300,
  "detailTimeoutSecs": 12,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "GOOGLE_SERP"
    ]
  }
}
```

# 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 = {
    "query": "software engineer",
    "location": "New York, NY",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "GOOGLE_SERP"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("searchapi/google-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 = {
    "query": "software engineer",
    "location": "New York, NY",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["GOOGLE_SERP"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("searchapi/google-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 '{
  "query": "software engineer",
  "location": "New York, NY",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "GOOGLE_SERP"
    ]
  }
}' |
apify call searchapi/google-jobs-scraper --silent --output-dataset

```

## MCP server setup

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