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

Scrape Google for Jobs. 22+ fields per posting (title, company, salary, apply links, remote flag). US/BR/MX/CA/UK/IN/AU/JP/SG. Pay only per job returned.

- **URL**: https://apify.com/gio21/google-jobs-scraper.md
- **Developed by:** [Gio](https://apify.com/gio21) (community)
- **Categories:** Jobs, Agents, AI
- **Features:** Limited permissions
- **Stats:** 1,490 total users, 96 monthly users, 100.0% runs succeeded, 4 bookmarks
- **User rating**: 2.44 out of 5 stars

## Pricing

$6.00 / 1,000 job scrapeds

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?

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: Salaries, Companies and Apply Links

**Google Jobs Scraper** pulls job listings from [Google for Jobs](https://www.google.com/search?udm=8) for any search query and location. Each posting comes back with title, company, salary range, employment type, remote flag, direct apply links, posting date and the full description.

It covers **9 countries** (United States, Brazil, Mexico, Canada, United Kingdom, India, Australia, Japan and Singapore) and needs **no login, no cookies and no proxy setup**.

Export to **JSON, CSV or Excel**, call it through the **API**, schedule it, or plug it into an **AI agent**.

### Quick start

1. Type one or more job titles in **Search queries** (for example `software engineer`).
2. Add a **Location** such as `San Francisco, CA`, or leave it empty for the whole country.
3. Pick the **Country** and click **Start**.

```json
{
  "queries": ["software engineer", "data analyst"],
  "location": "Austin, TX",
  "countryCode": "us",
  "datePosted": "week",
  "maxItems": 100
}
```

### What can you do with it?

- **Recruiting and sourcing:** see who is hiring for which roles in any city, with apply links straight to LinkedIn, Indeed, Greenhouse, Lever and company career pages.
- **Salary benchmarking:** collect disclosed `salaryMin` / `salaryMax` by role and city to build compensation bands.
- **Labor market research:** measure hiring demand, employment-type mix and posting volume across roles, companies and regions.
- **Remote job alerts:** filter with `workFromHome` and run it on a schedule to catch new remote openings.
- **AI and LLM datasets:** get clean, structured job JSON for RAG pipelines, agents and analysis.

### What data does it extract?

| Field | Description |
|-------|-------------|
| `title` | Job title |
| `companyName` / `companyLogo` | Hiring company and logo URL |
| `location` / `latitude` / `longitude` | Location text and coordinates when available |
| `salaryMin` / `salaryMax` / `salaryCurrency` / `salaryPeriod` | Disclosed pay range, currency and period (`HOUR`, `MONTH`, `YEAR`) |
| `jobType` / `workFromHome` | Employment type and remote flag |
| `description` / `descriptionHtml` | Job description as plain text and HTML |
| `benefits` / `qualifications` / `responsibilities` | Bullet lists parsed from the posting |
| `applyOptions` | Apply links per job board (LinkedIn, Indeed, Greenhouse, Lever, company ATS) |
| `postedAt` / `postedAtIso` / `postedVia` | How recent the posting is and which board published it |
| `jobId` / `sourceQuery` / `scrapedAt` | Identifier, the query that found it and extraction time |

### Input

| Field | Type | Description |
|-------|------|-------------|
| `queries` | Array | One or more search keywords, e.g. `["software engineer", "data scientist"]`. Each query runs on its own. |
| `location` | String | City, state or region, e.g. `"San Francisco, CA"`. Leave empty for country-wide results. |
| `countryCode` | String | `us`, `br`, `mx`, `ca`, `gb`, `in`, `au`, `jp` or `sg`. Default `us`. |
| `languageCode` | String | Language of the results, e.g. `en`, `pt`, `es`. Default `en`. |
| `datePosted` | String | `all`, `today`, `3days`, `week` or `month`. Default `all`. |
| `jobType` | Array | `FULLTIME`, `PARTTIME`, `CONTRACTOR`, `INTERN`. Empty means all types. |
| `workFromHome` | Boolean | Return only remote jobs. Default `false`. |
| `maxItems` | Integer | Maximum number of jobs after removing duplicates. Default 500, min 50, max 10,000. |
| `maxCost` | Number | Spending ceiling in USD for large runs (`maxItems` above 500). Default $2, max $20. |

Use `countryCode` and `languageCode` (not `country` / `language`). Google turned off its Jobs widget in the EU/EEA, so EU countries are not available.

### Output example

One record per job:

```json
{
  "jobId": "JqaxCjx4oqiOf07WAAAAAA==",
  "title": "Senior Software Engineer",
  "companyName": "Acme Inc",
  "location": "San Francisco, CA",
  "latitude": 37.7749,
  "longitude": -122.4194,
  "description": "We're hiring senior engineers for our infrastructure team...",
  "postedAt": "5 days ago",
  "postedAtIso": "2026-06-18T00:00:00.000Z",
  "jobType": "FULLTIME",
  "workFromHome": false,
  "salaryMin": 180000,
  "salaryMax": 240000,
  "salaryCurrency": "USD",
  "salaryPeriod": "YEAR",
  "benefits": ["Health insurance", "401(k)", "Stock options"],
  "qualifications": ["5+ years experience", "Go or Rust proficiency"],
  "applyOptions": [
    { "network": "linkedin", "url": "https://www.linkedin.com/jobs/view/...", "directApply": false },
    { "network": "greenhouse", "url": "https://boards.greenhouse.io/acme/jobs/...", "directApply": false }
  ],
  "postedVia": "LinkedIn",
  "sourceQuery": "software engineer",
  "scrapedAt": "2026-06-23T12:00:00.000Z"
}
```

#### Field notes

- **Salary fields** are filled only when the employer discloses pay. Otherwise they are `null`. Salaries in USD, EUR, GBP, JPY and INR are recognized.
- **`applyOptions`** has one entry per apply destination. The `url` is the real destination (Google's redirect is removed), so you get the actual LinkedIn, Greenhouse, Lever or company link.
- **`postedAt`** is Google's relative text ("5 days ago"). **`postedAtIso`** is the same date as ISO 8601.
- **`latitude`, `longitude` and `companyLogo`** are `null` when Google does not show them for that listing.
- **`jobId`** is Google's identifier when available. Otherwise it is built from title, company and location so you can deduplicate across runs.

### How many results can I get?

Google shows roughly 100 jobs per search. When `maxItems` is above 500, the scraper automatically splits the search by posting date and employment type and merges the results without duplicates, so you can go well past that limit. The `maxCost` setting keeps large runs within your budget.

For the widest coverage, use several specific queries together with a location.

### Pricing

You pay per job returned (see the **Pricing** tab for the current price). Runs that return no jobs cost nothing for results.

**Free Apify plan:** free accounts receive a small set of **sample jobs** (clearly marked with a `_notice` field) so you can see the output format. Real Google Jobs data requires a paid Apify plan.

### Integrations

- **API:** start runs and download results with the [Apify API](https://docs.apify.com/api/v2) or the JavaScript and Python clients.
- **Schedules:** run it [on a schedule](https://docs.apify.com/platform/schedules) for recurring job monitoring and get notified if a run fails.
- **AI agents (MCP):** let ChatGPT, Claude and other assistants call this scraper through the [Apify MCP server](https://mcp.apify.com).
- **No-code:** send results to Make, Zapier, Google Sheets, Slack or your database with [Apify integrations](https://docs.apify.com/platform/integrations) and webhooks.

### FAQ

**How does it work?**
It searches the Google Jobs widget the same way a job seeker would, opens each listing and turns the visible data (title, company, salary, apply links, description) into a structured dataset, at scale.

**Is it legal to scrape Google Jobs?**
It collects only publicly available job listings, with no login and no personal data. You are responsible for how you use the data and for following the laws and terms that apply to you. See [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Do I need a Google account?**
No. No account, cookies or credentials are needed. Unblocking is handled for you.

**Can I scrape only remote jobs?**
Yes. Set `workFromHome` to `true`. You can also filter by `jobType` and `datePosted`.

**My run succeeded but returned 0 jobs. Why?**
Sometimes Google shows a consent page with no job cards. The scraper detects it, reloads and retries with a fresh connection. If it still finds nothing, try a broader query or a different location. Empty runs are not charged for results.

**Why did I get sample data?**
You are on the free Apify plan. Upgrade to a paid plan to get real listings.

### Related scrapers

- **[Upwork Jobs Scraper](https://apify.com/gio21/upwork-jobs-scraper):** freelance projects from Upwork.
- **[Glassdoor Scraper](https://apify.com/gio21/glassdoor-scraper):** company reviews, salaries and ratings.
- **[Workana Scraper](https://apify.com/gio21/workana-scraper):** freelance projects from Workana (Latin America).
- **[Wellfound Jobs Scraper](https://apify.com/gio21/wellfound-jobs-scraper):** startup and tech jobs from Wellfound (AngelList).

### Feedback

Found a problem or need a field that is missing? Open an issue in the **Issues** tab and we usually reply within a day. If the scraper saved you time, a [review on the Apify Store](https://apify.com/gio21/google-jobs-scraper) helps a lot.

# Actor input Schema

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

One or more job-search keywords; each query runs independently and results are merged + deduped. Example: \["software engineer", "data scientist"]. For broad coverage, combine several specific queries with a location. Required field.

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

City, state or region to search within, e.g. "San Francisco, CA". Leave empty for country-wide results. Pairing a query with a location is the most reliable mode.

## `countryCode` (type: `string`):

ISO-2 country code that scopes the Google domain and locale, e.g. "us". One of: us, br, mx, ca, gb, in, au, jp, sg. EU/EEA countries are intentionally excluded (Google disabled the Jobs widget there after antitrust rulings). Use this field, not `country`.

## `languageCode` (type: `string`):

ISO 639-1 language code for the results UI/locale, e.g. "en", "pt", "es". Match it to your chosen country for best results. Use this field, not `language`.

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

Hard cap on the total number of jobs scraped across all queries, after dedup. Example: 500. Google shows ~100 per filter slice; setting this above 500 triggers automatic search-matrix expansion (rotating date/type filters) to get more.

## `datePosted` (type: `string`):

Filter listings by posting recency. One of: all, today, 3days, week, month. Example: "week" returns jobs posted in the past 7 days. Default "all" (no recency filter).

## `jobType` (type: `array`):

Filter by one or more employment types. Allowed values: FULLTIME, PARTTIME, CONTRACTOR, INTERN. Example: \["FULLTIME", "CONTRACTOR"]. Leave empty for all types.

## `workFromHome` (type: `boolean`):

When true, returns only remote / work-from-home roles. Example: true. Default false (all roles, remote and on-site). Combine with `jobType` and `datePosted` to narrow further.

## `maxCost` (type: `number`):

Hard ceiling, in USD, for proxy bandwidth cost when search-matrix expansion kicks in (only when maxItems > 500). Example: 2 caps a large run at ~$2. Default 2, min 0.25, max 20.

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

Advanced. The actor uses Brightdata Scraping Browser by default; this proxy is only used as a fallback. Leave as-is unless you have a reason to change it. Example: { "useApifyProxy": true, "apifyProxyGroups": \["RESIDENTIAL"] }.

## Actor input object example

```json
{
  "queries": [
    "software engineer"
  ],
  "location": "San Francisco, CA",
  "countryCode": "us",
  "languageCode": "en",
  "maxItems": 500,
  "datePosted": "all",
  "jobType": [],
  "workFromHome": false,
  "maxCost": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "queries": [
        "software engineer"
    ],
    "location": "San Francisco, CA",
    "countryCode": "us",
    "languageCode": "en",
    "maxItems": 500,
    "datePosted": "all",
    "maxCost": 2,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("gio21/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 = {
    "queries": ["software engineer"],
    "location": "San Francisco, CA",
    "countryCode": "us",
    "languageCode": "en",
    "maxItems": 500,
    "datePosted": "all",
    "maxCost": 2,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("gio21/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 '{
  "queries": [
    "software engineer"
  ],
  "location": "San Francisco, CA",
  "countryCode": "us",
  "languageCode": "en",
  "maxItems": 500,
  "datePosted": "all",
  "maxCost": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call gio21/google-jobs-scraper --silent --output-dataset

```

## MCP server setup

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