# Google Jobs Scraper Pro (`botflowtech/google-jobs-scraper-pro`) Actor

Scrape Google Jobs search results. Get job title, company, location, full description, salary, qualifications, benefits, and apply URL from any search query.

- **URL**: https://apify.com/botflowtech/google-jobs-scraper-pro.md
- **Developed by:** [BotFlowTech](https://apify.com/botflowtech) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 26 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.001 / job listing found

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

## Google Jobs Scraper Pro — Real-Time Job Data

> The most reliable Google Jobs scraper on Apify. Extract structured job listings from Google's jobs carousel at scale — including full descriptions, salary ranges, apply links, qualifications, and benefits.

***

### Why this scraper?

Most Google Jobs scrapers on Apify have sub-2/5 ratings because they use brittle CSS selectors, ignore dynamic rendering, and break within days of a Google UI update. **Google Jobs Scraper Pro** is built differently:

- **Multi-selector fallback chains** — every data field has 4–6 selector fallbacks so minor Google DOM changes don't break extraction
- **Playwright + stealth** — full headless Chrome automation with fingerprint masking and realistic browser headers
- **Proper detail panel handling** — clicks each job card to open the full detail pane before extracting long-form data (description, qualifications, benefits)
- **Smart pagination** — automatically loads more jobs until your `maxJobsPerQuery` limit is reached
- **PAY\_PER\_EVENT billing** — you only pay for jobs actually extracted, never for failed or empty requests

***

### Use cases

| Use case | Description |
|---|---|
| **Job aggregation** | Build a job board that pulls real-time listings from Google Jobs across any market |
| **Salary research** | Collect salary ranges from thousands of postings to benchmark compensation |
| **HR tech integration** | Feed structured job data into ATS platforms, analytics dashboards, or ML pipelines |
| **Recruitment automation** | Monitor competitors' hiring activity or track open roles at target companies |
| **Labour market analytics** | Analyse demand for skills, job titles, or locations over time |
| **Academic research** | Gather large datasets of job postings for NLP or economics research |

***

### Input

```json
{
    "queries": ["software engineer London", "data scientist remote"],
    "country": "gb",
    "language": "en",
    "maxJobsPerQuery": 100,
    "datePosted": "week",
    "jobType": "fulltime",
    "remoteOnly": false,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": ["RESIDENTIAL"]
    }
}
```

#### Input fields

| Field | Type | Default | Description |
|---|---|---|---|
| `queries` | `string[]` | **required** | Search queries, e.g. `["nurse London", "python developer remote"]` |
| `country` | `string` | `"us"` | ISO 3166-1 two-letter country code for localising results |
| `language` | `string` | `"en"` | ISO 639-1 two-letter language code |
| `maxJobsPerQuery` | `integer` | `50` | Max jobs to collect per query (1–500) |
| `datePosted` | `string` | `"any"` | Filter by posting date: `any`, `today`, `3days`, `week`, `month` |
| `jobType` | `string` | *(any)* | Filter by employment type: `fulltime`, `parttime`, `contractor`, `internship`, `temporary` |
| `remoteOnly` | `boolean` | `false` | Append "remote" to every query to target remote positions |
| `proxyConfiguration` | `object` | *(none)* | Apify Proxy or custom proxy config — residential proxies strongly recommended |

***

### Output

Each job listing is saved as a dataset item with the following schema:

```json
{
    "title": "Senior Software Engineer",
    "company": "Monzo",
    "location": "London, UK (Hybrid)",
    "description": "We are looking for a Senior Software Engineer to join our Platform Engineering team...",
    "salary": "£90,000 – £130,000 a year",
    "jobType": "Full-time",
    "datePosted": "3 days ago",
    "applyUrl": "https://boards.greenhouse.io/monzo/jobs/5678901",
    "source": "LinkedIn",
    "qualifications": [
        "5+ years of experience with Go or a similar compiled language",
        "Experience with distributed systems and microservices",
        "Strong understanding of system design principles"
    ],
    "benefits": [
        "Stock options",
        "Private health insurance",
        "Flexible working"
    ],
    "jobHighlights": [
        "Hybrid — 2 days in office",
        "90k–130k annually",
        "Full-time"
    ],
    "query": "software engineer London",
    "scrapedAt": "2026-04-01T10:00:00.000Z"
}
```

#### Output fields

| Field | Type | Description |
|---|---|---|
| `title` | `string` | Job title |
| `company` | `string` | Hiring company name |
| `location` | `string` | Office location or remote designation |
| `description` | `string` | Full job description (may include HTML) |
| `salary` | `string \| null` | Salary range if provided, otherwise `null` |
| `jobType` | `string \| null` | Employment type (Full-time, Part-time, Contract, etc.) |
| `datePosted` | `string \| null` | Human-readable posting date (e.g. "3 days ago") |
| `applyUrl` | `string \| null` | Direct application URL (company ATS or job board) |
| `source` | `string \| null` | Where the listing was posted (LinkedIn, Indeed, company site, etc.) |
| `qualifications` | `string[]` | Required/preferred qualifications bullet points |
| `benefits` | `string[]` | Benefits and perks |
| `jobHighlights` | `string[]` | Key job highlights shown at the top of the detail panel |
| `query` | `string` | The search query that produced this listing |
| `scrapedAt` | `string` | ISO 8601 timestamp of when the record was extracted |

***

### Pricing

**$1.00 per 1,000 jobs** (PAY\_PER\_EVENT)

You are charged only for jobs successfully extracted and pushed to the dataset. Empty results, failed pages, and pagination requests are not charged.

**Estimated costs for common workflows:**

| Workflow | Jobs | Cost |
|---|---|---|
| Quick search (1 query, 50 jobs) | 50 | ~$0.05 |
| Standard run (5 queries, 100 jobs each) | 500 | ~$0.50 |
| Large-scale collection (20 queries, 200 each) | 4,000 | ~$4.00 |
| Monthly market analysis (100 queries, 100 each) | 10,000 | ~$10.00 |

> Proxy costs are additional if using Apify Proxy. Residential proxies reduce blocking risk but cost more. For best reliability, use Residential proxy groups.

***

### Technical details

#### How it works

1. **URL construction** — builds a Google Jobs search URL: `https://www.google.com/search?q={query}&ibp=htl;jobs&hl={lang}&gl={country}`
2. **Page load** — navigates with full headless Chromium, applies stealth patches and rotates User-Agents from a pool of 7 real Chrome versions
3. **Job card iteration** — locates all job card `<li>` elements in the Google Jobs panel
4. **Detail extraction** — clicks each card to open the right-side detail panel, then extracts all structured fields using multi-fallback selectors
5. **Pagination** — clicks "More jobs" button repeatedly until `maxJobsPerQuery` is reached or no more results exist
6. **PAY\_PER\_EVENT charging** — charges `job-result` event for each record pushed to the dataset

#### Anti-detection

- Headless Chrome with `--disable-blink-features=AutomationControlled`
- `navigator.webdriver` masked
- Realistic `User-Agent`, `Accept-Language`, `Sec-Ch-Ua` headers
- Viewport randomisation (1280–1480 × 900–1000px)
- Crawlee fingerprint generator (desktop Chrome 110+, Windows/macOS)
- Random delays between 800ms–2200ms between actions
- Cookie consent banner auto-dismissal

#### Error handling

- Automatic retry up to 3 times per URL
- CAPTCHA / "unusual traffic" detection with error logging
- Per-field fallback selectors survive minor Google DOM changes
- Gracefully skips cards where extraction returns empty data

***

### Requirements

- **Node.js** >= 18
- **Apify SDK** v3
- **Playwright** >= 1.42
- Recommended: Apify Residential proxies for large runs

#### Local development

```bash
git clone <repo>
cd google-jobs-scraper-pro
npm install
npx playwright install chromium
npm run dev
```

Create a `storage/key_value_stores/default/INPUT.json` file with your input before running locally.

***

### Changelog

#### v1.0.0

- Initial release
- Full Google Jobs extraction: title, company, location, description, salary, job type, date posted, apply URL, source, qualifications, benefits, highlights
- PAY\_PER\_EVENT billing at $1.00 / 1,000 jobs
- Stealth mode with fingerprint rotation
- Pagination support via "More jobs" button
- Support for country, language, date posted, job type, and remote-only filters

***

### Related actors

- **LinkedIn Jobs Scraper** — extract jobs from LinkedIn
- **Indeed Scraper** — scrape Indeed.com job listings
- **Glassdoor Scraper** — jobs + company reviews

***

*Built with [Apify SDK v3](https://docs.apify.com/sdk/js/) and [Crawlee](https://crawlee.dev/).*

# Actor input Schema

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

One or more job search queries. Each query is a string describing the role and/or location, e.g. `software engineer London`, `data scientist remote`, `nurse New York`. The scraper will run each query independently.

## `country` (type: `string`):

Two-letter ISO 3166-1 country code for localising Google Jobs results. Examples: `us`, `gb`, `de`, `fr`, `au`, `ca`, `in`.

## `language` (type: `string`):

Two-letter ISO 639-1 language code for the search interface. Examples: `en`, `de`, `fr`, `es`.

## `maxJobsPerQuery` (type: `integer`):

Maximum number of job listings to collect for each search query. Set to `0` for unlimited (scraper will stop when Google has no more results).

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

Filter jobs by how recently they were posted.

## `jobType` (type: `string`):

Filter by employment type. Leave blank to include all job types.

## `remoteOnly` (type: `boolean`):

When enabled, appends `remote` to each search query to target remote positions.

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

Proxy configuration for the scraper. Use Apify Proxy or a custom proxy to avoid rate limits and improve success rates. Residential proxies are recommended for large-scale scraping.

## Actor input object example

```json
{
  "queries": [
    "software engineer London",
    "data scientist remote"
  ],
  "country": "us",
  "language": "en",
  "maxJobsPerQuery": 50,
  "datePosted": "any",
  "remoteOnly": false,
  "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 London",
        "data scientist remote"
    ],
    "country": "us",
    "language": "en",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("botflowtech/google-jobs-scraper-pro").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 London",
        "data scientist remote",
    ],
    "country": "us",
    "language": "en",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("botflowtech/google-jobs-scraper-pro").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 London",
    "data scientist remote"
  ],
  "country": "us",
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call botflowtech/google-jobs-scraper-pro --silent --output-dataset

```

## MCP server setup

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

```

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/PTWahJFdYd10KqAg7/builds/bxlgBa3VtDPmdxKnc/openapi.json
