# Apify Google Jobs Scraper

> Run a google jobs scraper that bills per listing, not per page, with the Apify Google Jobs Scraper API Pay Per Result Actor (johnvc/google-jobs-scraper---pay-per-result). Give a job title plus an optional location and get one flat row per opening with title, company_name, location, via (source platform), full description, job_highlights, detected_extensions (posted_at, schedule_type), apply_options direct links, source_link, and job_id. Built-in company_filter and via_filter drop unwanted employers or job boards before you pay for them. Use when the user asks for a google jobs scraper, wants to scrape Google Jobs openings for a role or city, needs a job listings dataset with predictable cost, or wants to exclude staffing agencies from the results. Pay-per-result billing, MCP-ready for Claude and other AI agents.

- Skill: `johnisanerd/apify-google-jobs-scraper` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add johnisanerd/apify-google-jobs-scraper`
- Raw SKILL.md: https://api.skillmd.com/api/skills/johnisanerd/apify-google-jobs-scraper/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: johnisanerd (https://skillmd.com/u/johnisanerd)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/johnisanerd/apify-google-jobs-scraper

---


# Google Jobs Scraper With Per-Result Billing

A Google Jobs scraper that charges for every listing it hands you and nothing else. Give it a role and a location, get one flat row per opening, and know the bill before the run starts because the math is results times price.

## When to use this skill

- The user asks for a "google jobs scraper" or wants to scrape Google Jobs openings.
- They want listings for a role, company, city, or country as a flat dataset.
- They want cost that scales with rows delivered rather than pages fetched.
- They want to exclude specific employers or job boards from the output.

Not for: salary analytics (there is no numeric salary field), LinkedIn-only listings (use the LinkedIn Jobs API), or employer reviews (use the Glassdoor Reviews API).

## What you get (one flat row per listing)

Verified on a live run:

- `title` and `job_title` (identical strings, so pick either one)
- `company_name`, `location`, `via` (the platform hosting the listing, such as LinkedIn or a company careers site)
- `description` (full posting text, often 1,500 characters or more)
- `job_highlights` (array of `{title, items}` blocks such as Qualifications, Responsibilities, Benefits)
- `extensions` (raw tag strings such as "22 hours ago", "Full-time")
- `detected_extensions` (`posted_at` and `schedule_type` on every row, plus `work_from_home` and `qualifications` when present on that listing)
- `apply_options` (array of `{title, link}` direct apply links, one per hosting platform)
- `source_link` (canonical link to the posting), `share_link` (Google Jobs permalink), `job_id` (dedupe key)
- Echoed run context on every row: `query`, `country`, `language`, `google_domain`, `search_timestamp`, `total_jobs_found`, `pages_processed`

Every row carries its own search context, so you can merge several runs into one table and still tell where each listing came from.

## Prerequisites

- Apify account (sign up at https://apify.com?fpr=9n7kx3&fp_sid=skillrepo).
- Authentication via `apify login`, or an `APIFY_TOKEN` environment variable (Apify Console, Settings, Integrations).

## The Actor

- Store page: https://apify.com/johnvc/google-jobs-scraper---pay-per-result?fpr=9n7kx3&fp_sid=skillrepo
- Actor ID: `johnvc/google-jobs-scraper---pay-per-result`
- Pricing: pay per result delivered to the dataset (see `references/gotchas.md`).

## Run it with the Apify CLI

Scrape a role in a city, capped at 10 listings:

```bash
apify actors call "johnvc/google-jobs-scraper---pay-per-result" -i '{"query":"software engineer","location":"Austin, TX","country":"us","language":"en","num_results":10}' \
  --json \
  --user-agent apify-awesome-skills/apify-google-jobs-scraper \
  2>/dev/null
```

Scrape a country-wide search on a local Google domain, skipping two job boards:

```bash
apify actors call "johnvc/google-jobs-scraper---pay-per-result" -i '{"query":"data analyst","location":"United Kingdom","country":"uk","google_domain":"google.co.uk","language":"en","num_results":50,"via_filter_list":["Indeed","ZipRecruiter"]}' \
  --json \
  --user-agent apify-awesome-skills/apify-google-jobs-scraper \
  2>/dev/null
```

Every call carries the three flags this repo expects: `--json` (or `--format json`), `--user-agent apify-awesome-skills/apify-google-jobs-scraper`, and `2>/dev/null`.

## Run it from Claude or another AI agent (MCP)

The Actor is MCP-ready. Add the hosted server URL:

`https://mcp.apify.com/?tools=actors,docs,johnvc/google-jobs-scraper---pay-per-result`

Then ask, for example: "Scrape Google Jobs for 20 warehouse supervisor openings near Columbus and give me the apply links." MCP setup docs: https://docs.apify.com/platform/integrations/mcp

## Workflow

1. Build the query. `query` is the only required field, and it takes a job title, skill, or company name. Add `location` (city, state, or country) to narrow it.
2. Set localization. Send `country` and `language` explicitly. Google Jobs returns nothing when neither is supplied, and the Actor has to guess from `google_domain` and log a warning.
3. Cap the volume. `num_results` is the direct cost lever here because you pay per row. The minimum accepted value is 10; the maximum is 1000.
4. Filter before you pay. `company_filter_list` and `via_filter_list` drop matching rows during collection, so excluded listings never reach the dataset and never get billed.
5. Estimate cost, then confirm with the user if the run is large. See `references/gotchas.md`.
6. Run the Actor and read the dataset. Dedupe across runs on `job_id`.

## Inputs

- `query` (string, required): job title, skill, or company
- `location` (string): city, state, or country. Empty plus a `country` value falls back to the country name
- `country` (enum: None, us, ca, uk, de, fr, au, jp, in, br, mx)
- `language` (enum, 100 plus codes, default None)
- `google_domain` (enum, default `google.com`)
- `num_results` (integer 10 to 1000, default 100): the billing lever
- `max_pagination` (integer 0 to 100, default 0 = unlimited)
- `company_filter` (string, comma separated) or `company_filter_list` (array): exclude employers
- `company_filter_regex` (boolean, default false): treat the company filters as regular expressions
- `via_filter` (string) or `via_filter_list` (array): exclude source platforms
- `include_lrad` (boolean) plus `lrad_value` (string, miles): radius search
- `max_delay` (integer 0 to 10, default 1): seconds between requests
- `output_file` (string): custom filename for the saved results file

## Cost

Billing is per result in the default dataset. Ten listings cost ten result charges, one hundred listings cost one hundred. Live per-result prices and confirmation thresholds are in `references/gotchas.md`.

## Honest limits

- No numeric salary field and no experience-level field. Pay figures sometimes appear inside `job_highlights` Benefits text, but that is free text you would have to parse yourself, not a structured field.
- `posted_at` is a relative string such as "22 hours ago", so freshness filtering happens on your side after the run.
- `pages_processed` came back as 0 on the verified run, so treat it as unreliable and count dataset rows instead.
- Google Jobs inventory varies by region and query, so `num_results` is a cap and not a guarantee.
- Company and source filters are case sensitive unless you turn on `company_filter_regex`.

## Troubleshooting

- No results: send `country` and `language` explicitly, then broaden the query or drop the location.
- Fewer rows than `num_results`: normal, Google had fewer listings for that query.
- Insufficient funds: the Actor writes a single error row explaining the shortfall instead of failing silently. Add funds or lower `num_results`.

See `references/gotchas.md` for cost guardrails and error recovery, and `references/actor-index.md` for the Actor routing table.

## Related job-data Actors

- Google Jobs Scraper, pay per page edition: https://apify.com/johnvc/Google-Jobs-Scraper?fpr=9n7kx3&fp_sid=skillrepo
- LinkedIn Jobs API: https://apify.com/johnvc/linkedin-jobs-api?fpr=9n7kx3&fp_sid=skillrepo
- Glassdoor Reviews API: https://apify.com/johnvc/glassdoor-reviews-api?fpr=9n7kx3&fp_sid=skillrepo

