DEV Community

CleanScrape
CleanScrape

Posted on

What a data analyst earns in New York, Chicago and Austin, from 150 Google Jobs listings

Google Jobs is the job search built into Google. It pulls listings from LinkedIn, Indeed, Glassdoor, company career sites and local job boards into one place, which makes it a good single source when you want to compare jobs across cities. It has no public API, so I built a small tool on Apify that turns a Google Jobs search into a table.

Here is one real use: I wanted to see what data analyst jobs pay in New York, Chicago and Austin.

The search

The input is a job title and a list of locations. Every title is searched in every location:

{
  "queries": ["data analyst"],
  "locations": ["New York, NY", "Chicago, IL", "Austin, TX"],
  "maxJobsPerSearch": 50
}
Enter fullscreen mode Exit fullscreen mode

The run returned 150 jobs in 43 seconds. Most came via LinkedIn (34), Indeed (16), Dice (8) and Monster (8); the rest from company career sites and smaller boards.

Salaries as numbers

Google shows pay as text, such as "$124K–$177K a year" or "$57.70–$62.50 an hour". The tool splits that into salaryMin, salaryMax, salaryCurrency and salaryPeriod, so you can sort and filter without parsing anything yourself.

64 of the 150 jobs listed a salary. Taking the midpoint of each yearly range and the median per city:

City Jobs with a yearly salary Median of range midpoints
New York 21 $106,734
Chicago 19 $97,500
Austin 13 $110,000

These are small samples from one search on October 6, 2026, not a salary survey. Austin coming out on top surprised me; with 13 jobs it can easily move by the next run.

In Python, with the Apify client:

from statistics import median
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("cleanscrape/google-jobs-scraper").call(run_input={
    "queries": ["data analyst"],
    "locations": ["New York, NY", "Chicago, IL", "Austin, TX"],
    "maxJobsPerSearch": 50,
})
jobs = list(client.dataset(run["defaultDatasetId"]).iterate_items())
for city in ["New York, NY", "Chicago, IL", "Austin, TX"]:
    mids = [(j["salaryMin"] + j["salaryMax"]) / 2 for j in jobs
            if j["searchLocation"] == city and j["salaryPeriod"] == "year"]
    print(city, len(mids), median(mids) if mids else None)
Enter fullscreen mode Exit fullscreen mode

More than 10 jobs per search

Google Jobs shows 10 jobs per search. To get more, the tool runs close variations of the same search (posted today, this week, full time, remote, senior and so on) and keeps each job once. A search stops when the variations stop finding new jobs, so a narrow search ends early instead of paying for repeats.

Only new jobs

For job alerts, turn on "Only jobs not saved before" and schedule the task. Each run returns only jobs earlier runs did not save, and the skipped ones are not charged.

Try it

Google Jobs Scraper on Apify. You pay per job saved, and the run above cost about $0.29. It works in 36 countries; outside English-speaking ones, type the job title in the local language.

Top comments (0)