# Google Jobs Scraper for job lists with salary and apply links

> Google Jobs scraper for job titles, companies, salary text, dates and apply links. Pick a city and country. No Google login or API key. Export to CSV.

URL: https://cliqtomedia.com/actors/google-jobs-scraper/

Category: Jobs & hiring · Status: live on Apify Store · Apify page: https://apify.com/cliqtomedia/google-jobs-scraper?fpr=cliqto

Type a job title and a city. You get the jobs Google shows, one row per job. Each row has the company, salary text, posting age and the links to apply.

## How to use it: 3 steps

1. **Make a free Apify account.** Apify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
2. **Paste your input and press Start.** No code needed: you fill in a form (the input). It already has a working example. For example: `python developer` in Job searches. Each start is one run.
3. **Download the results.** When the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

## What it does

Google Jobs Scraper searches Google Jobs for your job titles and a location and returns one row per job: title, company, location, salary, job type, posting age, full description and the apply links to LinkedIn, Indeed or the employer site. It reads the public Google Jobs results page, so you need no Google login and no API key. The default input (`python developer` in Berlin, 10 jobs) usually takes 10–60 seconds and costs $0.033.

- You add one or more job searches, for example `python developer` or `registered nurse`, and a location.
- The Actor opens the Google Jobs results page for each search in the right Google country.
- It reads every job card: title, company, location, the site Google found the job on (`via`), posting age, salary and job type.
- It reads the job panel too: the full description, Google's highlights and all apply links, without tracking parameters.
- It removes duplicate jobs (same Google job id) and saves one Dataset row per job.
- Fast mode reads one Google page per search, about 10 jobs. Deep mode repeats each search with Google's date and job-type filters and removes duplicates, so you get several times more jobs.

### Good for

- Job market research: who hires for a role in a city, and on which job boards.
- Lead lists for recruiters and staffing agencies: companies with open roles, with the link to each job.
- Salary checks: Google's salary text where the job has one.
- A daily job feed for a niche job board, a Slack channel or a spreadsheet.

### Not a good fit

- 8 countries only: United States, United Kingdom, Canada, India, Germany, France, Spain and Brazil (`countryCode`). Google shows the texts in the language of that country, for example `vor 1 Tag` and `Vollzeit` in Germany.
- Google shows about 10 jobs per search page. Fast mode gives about 10 jobs per search; deep mode about 20–70 (our tests). For more jobs, add more searches (up to 50) or more specific titles.
- `salary` is often `null`: Google shows a salary only for some jobs (0–40 % in our tests).
- `highlights` is often `null` in fast mode: Google does not send this block on many pages. The full `description` is still there.
- No recruiter names, emails or phone numbers. The Actor saves only the public job post.
- Google decides which jobs it shows. Two runs a few minutes apart can return a slightly different set or order.
- Google's terms do not allow automated access to Google Search. You are responsible for how you use the data.

## Price

Pay per event. Apify bills you, not us.

| What you pay for | Price | When |
|---|---|---|
| Start fee | $0.01 | Charged once per run. This tool uses 1 GB of memory or less by default; more memory costs more. |
| Google Jobs search page | $0.013 | One Google Jobs results page that Google answered (up to 10 jobs), including pages with no jobs. Pages that failed are not charged. |
| Job listing | $0.001 (from $0.00085 on paid Apify plans) | One unique job saved to the Dataset. Duplicates, not_found and error rows are free. |

- One result: about $0.01.
- 1,000 results: about $1.01.
- Every day 100 results, for 30 days: about $3.30 a month.

Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed.

Prices checked on 24 October 2026. Current price: https://apify.com/cliqtomedia/google-jobs-scraper?fpr=cliqto

## Questions

### Can I scrape Google Jobs without a Google account?

Yes. The tool reads the public Google Jobs page. You need no login, cookies or API key.

### Which countries can I search?

Eight countries: the US, UK, Canada, India, Germany, France, Spain and Brazil.

### How many jobs do I get per search?

Fast mode gives about 10 jobs per search. Deep mode gave about 20 to 70 in tests.

### Why do many jobs have no salary?

Google shows a salary only when the job post has one. The tool never guesses a salary.

### Do I need a Google account or API key?

No. The Actor reads the public Google Jobs results page without login, cookies or keys.

### Is this the official Google Jobs API?

No. Google has no public API for Google Jobs search results. This Actor is not made by or linked to Google.

### Why are some texts in German or French?

Google shows jobs in the language of the country you search. Search in Germany, and `postedAt` says `vor 2 Tagen` and `employmentType` says `Vollzeit`. `postedAtApprox` gives a date that is the same in every language.

### Why is salary empty for most jobs?

Google shows a salary only when the job post or job board gives one. The Actor does not guess: no salary on Google means `salary: null`.

### Can I get the recruiter's email or phone?

No. The Actor saves only the public job post and does not collect personal contact data.

## Data fields

- `status` (string): complete: a job; partial: a deep search where some Google pages did not answer (jobs of the other pages are in their own rows); not_found: Google has no jobs for this search; error: Google did not answer.
- `title` (string): Job title as the employer wrote it.
- `company` (string): Employer name.
- `location` (string): Job location as Google shows it, e.g. "Berlin, Germany" or "Anywhere".
- `via` (string): Site Google found the job on, e.g. "LinkedIn" or "via Indeed".
- `postedAt` (string): Posting age as Google shows it, e.g. "2 days ago" or "vor 1 Tag"; null when Google does not show it.
- `postedAtApprox` (string): Approximate posting date (YYYY-MM-DD) = fetchedAt minus postedAt; null for open ranges such as "30+ days ago".
- `salary` (string): Salary as Google shows it, e.g. "$104K–$156K a year"; null when the job has no salary (not 0).
- `employmentType` (string): Job type as Google shows it, e.g. "Full-time" or "Vollzeit".
- `workFromHome` (boolean): true when Google tags the job as work from home; null when it does not say.
- `description` (string): Full job description as plain text; null when includeDescription is off.
- `highlights` (array): Google's job highlights (Qualifications, Responsibilities, Benefits); null when Google shows none or includeDescription is off.
- `applyLinks` (array): Where to apply: the employer site and job boards, with tracking parameters removed.
- `jobId` (string): Google's job id; the same job has the same id across searches and runs.
- `googleJobsUrl` (string): Google Jobs page that opens this job.
- `position` (integer): Order of the job in this search's results (1 = first, after removing duplicates); null on status rows.
- `query` (string): Your job search.
- `searchLocation` (string): Location from your input; null when empty.
- `countryCode` (string): Google country searched (us, gb, ca, in, de, fr, es, br).
- `searchVariant` (string): Deep mode: which search found the job (base, datePosted:week, employmentType:parttime…); null in fast mode.
- `source` (string): Always google_jobs.
- `sourceUrl` (string): Google search URL that was fetched.
- `fetchedAt` (string): When the page was fetched (ISO 8601, UTC).
- `statusReason` (string): Why the row is partial, not_found or error; null on complete rows.
- `errorCode` (string): Machine-readable error code on error rows, e.g. SOURCE_TIMEOUT; null otherwise.

## Input settings

- `queries` (array, required): What to search on Google Jobs, one per line, e.g. "python developer" or "registered nurse". Up to 50 searches; duplicates are removed.
- `location` (string): City, region or "remote", added to every search, e.g. "Berlin", "Austin, TX" or "London". Leave empty to search the whole country: Google Jobs needs a place, so the country name is added ("nurse" → "nurse USA").
- `countryCode` (string): Google country and language to search in. Auto picks it from the location ("Berlin" → Germany, "Austin, TX" → United States); unknown places use the United States.
- `datePosted` (string): Only jobs posted in this period. Uses Google's own date filter, then drops jobs whose shown posting date is older (they are not written or charged).
- `employmentType` (string): Only jobs of this type. Uses Google's own job-type filter, then drops jobs whose shown job type is a different one (not written or charged).
- `mode` (string): Google Jobs shows about 10 jobs per search. Deep mode repeats each search with Google's date and job-type filters and removes duplicates, so you get several times more jobs.
- `maxJobs` (integer): Stop after this many jobs in total for the run. You pay only for jobs written to the Dataset.
- `includeDescription` (boolean): Add the full job description and Google's highlights (qualifications, responsibilities, benefits). Turn off for smaller rows.

## Step by step on Apify

1. Open the Input tab.
2. In Job searches (`queries`), keep `python developer` or add your own job title.
3. Keep Location `Berlin` and Max jobs `10`, or change them. Country `auto` picks the country from the location.
4. Click Start.
5. Open the Output tab. The Jobs table shows `title`, `company`, `location`, `salary` and the apply links.

## Use cases

| Task | Input | You get | Key fields | Next step |
|---|---|---|---|---|
| Job market research | `queries` + `location`, `mode: "deep"` | Job | `title`, `company`, `via`, `postedAt` | CSV or Excel export |
| Recruiting lead list | `queries` like `"sales manager"` + `datePosted: "week"` | Job | `company`, `title`, `location`, `applyLinks` | Google Sheets or CRM through Apify integrations |
| Salary check | `queries` + `location` | Job | `salary`, `employmentType`, `title` | Spreadsheet |
| Daily job feed | `queries` + `datePosted: "today"` on a schedule | Job | `jobId`, `title`, `googleJobsUrl` | Slack, email or a website through webhooks |

## Tips

- Use deep mode when one search gives too few jobs. It finds several times more.
- Add more specific titles, like "junior python developer", to get more unique jobs.
- Use postedAtApprox to sort by date. It works the same in every language.

## Sample result

```json
{
  "status": "complete",
  "title": "Python Team Lead, Integration team",
  "company": "Fliff Inc",
  "location": "Beliebiger Ort",
  "via": "LinkedIn",
  "postedAt": "vor 1 Tag",
  "postedAtApprox": "2026-10-14",
  "salary": null,
  "employmentType": "Vollzeit",
  "workFromHome": true,
  "description": "We’re looking for a Python Team Lead to join our Integration team, which owns a broad set of critical integrations across the product…",
  "highlights": null,
  "applyLinks": [
    { "title": "LinkedIn", "url": "https://de.linkedin.com/jobs/view/python-team-lead-integration-team-at-fliff-inc-4479228357" },
    { "title": "Startup Jobs", "url": "https://startup.jobs/python-team-lead-integration-team-fliff-inc-10437417" }
  ],
  "jobId": "eAHxzL0ATotpbjXSAAAAAA==",
  "googleJobsUrl": "https://www.google.de/search?ibp=htl;jobs&q=python+developer+Berlin&htidocid=eAHxzL0ATotpbjXSAAAAAA%3D%3D&hl=de-DE#…",
  "position": 2,
  "query": "python developer",
  "searchLocation": "Berlin",
  "countryCode": "de",
  "searchVariant": null,
  "source": "google_jobs",
  "sourceUrl": "https://www.google.de/search?q=python+developer+Berlin&udm=8&hl=de&gl=de",
  "fetchedAt": "2026-10-15T06:20:55.335Z",
  "statusReason": null,
  "errorCode": null
}
```

## Use it from code

Actor ID: `cliqtomedia/google-jobs-scraper`

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/google-jobs-scraper").call(run_input={
    "queries": [
        "python developer"
    ],
    "location": "Berlin"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

```bash
curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~google-jobs-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries": ["python developer"], "location": "Berlin"}'
```

```python
# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("cliqtomedia/google-jobs-scraper")
result = tool.invoke({"run_input": {"queries": ["python developer"], "location": "Berlin"}})
print(result)
```

run-sync waits up to 300 seconds; for longer runs start a run and use a webhook. LlamaIndex and MCP: https://cliqtomedia.com/actors/ai-agents/

## Similar tools

- [Remote Jobs Aggregator - RemoteOK, WWR & Himalayas, No login](https://cliqtomedia.com/actors/remote-jobs-aggregator/)
- [Greenhouse Jobs Monitor & Scraper](https://cliqtomedia.com/actors/greenhouse-jobs-monitor-scraper/)
- [Lever Job Scraper](https://cliqtomedia.com/actors/lever-jobs-scraper/)
- [Wellfound Jobs Scraper](https://cliqtomedia.com/actors/wellfound-jobs-scraper/)
- [Ashby Jobs Scraper](https://cliqtomedia.com/actors/ashby-jobs-scraper/)
- [Recruitee Job Snapshots & Changes](https://cliqtomedia.com/actors/recruitee-jobs-monitor-scraper/)
