Real Estate Agents Scraper: Google Maps Agencies
Pricing
from $2.00 / 1,000 results
Real Estate Agents Scraper: Google Maps Agencies
Search Google Maps for real estate agencies and agents in any city. Get clean, de-duplicated records: name, address, phone, website, rating, categories, coordinates and Google Place ID. Optional weekly monitoring lists new agencies. No API key, no login.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
Turgay NANTA
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
20 days ago
Last modified
Categories
Share
Real Estate Agents Scraper for Google Maps: Agencies, Phones, Websites and Place IDs
Finding every real estate agency in a city by hand means scrolling Google Maps, copying names into a spreadsheet, and losing track of which office you already called. Paid place APIs need a Google Cloud project, an API key and a billing account before you see a single row.
This Actor searches Google Maps for real estate agencies and agents in any city and returns clean, de-duplicated business records: name, full address, phone number, website, primary and secondary categories, star rating, coordinates, time zone and the official Google Place ID. No API key, no Google Cloud account, no login.
- Who it is for: brokerages recruiting agents, proptech and mortgage sales teams, marketing agencies that sell to realtors, market researchers and AI agents that need local real estate data.
- What it costs: about $0.04 for 20 agencies (a $0.0001 start fee plus $0.002 per record). Optional enrichment and change alerts are priced separately. See Pricing.
- One click: every field has a working default (
real estate agency Austin TX), so you can press Start and see real output before changing anything. - Scheduled monitoring: turn on
monitor, schedule the same query weekly, and each run lists the Place IDs of agencies that were not in the previous run.
Agencies, not property listings. This Actor returns real estate businesses as they appear on Google Maps. It does not return homes for sale, rental listings, prices or MLS data.
What one output record looks like
This record comes from a live capture of the query real estate agency Seattle WA:
{"id": "ChIJOR9o-cBBkFQRR-k_PH6pJzc","title": "Every Door Real Estate","url": "https://www.everydoorrealestate.com/","location": "5506 6th Ave S #204, Seattle, WA 98108","phone": "+12062220531","rating": 4.9,"category": "Real estate agency","categories": ["Real estate agency", "Commercial real estate agency", "Real estate agent", "Real estate consultant", "Real estate developer"],"lat": 47.5531558,"lng": -122.3260943,"place_id": "ChIJOR9o-cBBkFQRR-k_PH6pJzc","timezone": "America/Los_Angeles","photo": "https://lh4.googleusercontent.com/-BapoiMOP6YM/AAAAAAAAAAI/AAAAAAAAAAA/NNgzBJxuClU/s44-p-k-no-ns-nd/photo.jpg"}
The record also carries a few shared columns that stay empty for Google Maps data (price, price_text, seller, reviews, description); they are explained in the Output section.
At a glance
| Input | One Google Maps search query, for example real estate agency Denver CO or realtor Miami Beach |
| Output | One clean record per business + a _summary row (+ a _changes row in monitor mode) |
| Key fields | title, phone, url (website), location (address), rating, category, categories, place_id, lat, lng, timezone, photo |
| Results per query | Up to about 20 businesses (one Google Maps results page) |
| De-duplication | By Google Place ID, so two offices of the same franchise stay separate |
| Monitoring | Optional: flags businesses that are new since the previous run of the same query |
| Technology | Real headless Chromium browser (Playwright); reads the same structured data Google Maps uses to draw its result list |
| API key needed | No |
| Runs on | Apify Console, API, schedules, n8n, Make, Zapier, AI agents via MCP |
Quick start (1 minute)
- Click Start. The default query
real estate agency Austin TXruns as is. - When the run finishes, open the Dataset tab. The Results view shows name, phone, website, address, rating, category and Place ID.
- Export as CSV, Excel, JSON or HTML, or fetch the items through the API.
Then replace the query with your own market:
{"query": "real estate agency Denver CO","maxResults": 20}
Good query patterns:
real estate agency <city> <state>for brokerages and officesrealtor <neighborhood or ZIP>for individual agents and small teamscommercial real estate agency <city>for the commercial segmentproperty management company <city>orreal estate appraiser <city>for adjacent real estate businesses
Why people use it
General Google Maps scrapers are built for every business type at once. This Actor does one narrow job:
- It is ready for real estate queries out of the box. The default query, the table view and the documentation are built around agencies and agents.
- It returns the official Google Place ID for every business. The Place ID is stable, so you can use it as the primary key in your CRM, join runs over time, or pass it to Google's own APIs later.
- It de-duplicates by Place ID. Franchise offices often share one website (for example a brand homepage). Because the Actor keys records by Place ID, two branches with the same website remain two records, while the same office seen twice collapses into one.
- It normalizes the output. Websites are canonicalized (tracking parameters such as
utm_*,ref,fbclidandgclidare removed), text is trimmed, and the rating is a number, not a string. - It watches a market for you. With
monitoron and a schedule, each run reports only the agencies that were not there last time. - No LLM. Every field comes from Google's own data, so nothing is invented.
Use cases by profession
Brokerages and team leaders recruiting agents
Pull every agency and independent agent in the neighborhoods you want to grow into. Sort by rating to see well-reviewed competitors, and use categories to separate brokerages ("Real estate agency") from individual agents ("Real estate agent"). Put the Place ID in your recruiting CRM so the same office is never contacted twice.
Mortgage brokers, title and escrow companies, home inspectors
Your best referral partners are local agencies. Build a partner list per ZIP code with phone and website, then schedule a weekly monitored run to catch new offices as they open, before competitors reach them.
Proptech and SaaS sales teams
If you sell CRM, lead generation, photography, virtual staging or transaction software to realtors, this is a clean top-of-funnel list. Each record has a website domain you can enrich with your email-finding tool of choice, and coordinates you can map to sales territories.
Marketing and web agencies serving realtors
Search a city, filter records where url is empty, and you have agencies without a website on their Google Maps profile. Filter by low rating for businesses that may need reputation help. Both are simple dataset filters, no extra tooling.
Market researchers and analysts
Count agencies per neighborhood, compare ratings across markets, and plot coordinates on a map to see clustering.
AI agents and automations
An AI assistant that researches a local market can call this Actor through the Apify MCP server and receive typed, flat JSON, instead of writing and maintaining its own browser code.
How it works
- Opens Google Maps in a real browser. The Actor launches headless Chromium with Playwright and opens
https://www.google.com/maps/search/<your query>?hl=en. - Captures the data response. Google Maps does not put search results in the initial HTML. It loads them afterwards through a background request. The Actor listens to network traffic and captures that response, including Google's anti-hijacking prefix, which it strips before parsing.
- Parses each business. From the structured response it reads the name, full address, website, phone, star rating, categories, coordinates, time zone, Place ID and cover photo. Entries without a name are skipped.
- Normalizes and de-duplicates. Text is cleaned, URLs are canonicalized, and records are de-duplicated by Place ID. The run summary tells you how many duplicates were merged.
- Optionally enriches each record with a canonical
domainand acompletenessscore. - Optionally compares with the previous run of the same query and writes a
_changesrow with the Place IDs that are new. - Writes a
_summaryrow with totals for the run.
No Google account, cookies or API keys are used. The Actor requests English results (hl=en); Google may still localize category names and addresses depending on where the request comes from.
Input
All fields are optional. An empty input runs the default example.
| Field | Type | Default | Description |
|---|---|---|---|
query | string | real estate agency Austin TX | What to search on Google Maps. Niche plus location works best. |
maxResults | integer | 20 | Maximum number of clean records to return (1-500). One query returns up to about 20 businesses, so values above 20 do not add results. |
enrich | boolean | false | Adds domain and completeness to every record. Charged per enriched record. |
monitor | boolean | false | Compares this run with the previous monitored run of the same query and writes a _changes row with new Place IDs. Charged per new record. |
Example: one neighborhood
{"query": "realtor Capitol Hill Seattle","maxResults": 20}
Example: weekly market watch
{"query": "real estate agency Boise ID","monitor": true}
Save this as a Task and attach a weekly Schedule to it (see Integrations).
Output
Dataset records (one per business)
| Field | Description |
|---|---|
id | Google Place ID (same as place_id); used for de-duplication and monitoring |
title | Business name as shown on Google Maps |
url | Website from the Maps profile, canonicalized (tracking parameters removed); empty if the business lists none |
location | Full formatted address (one line, without the business name) |
phone | Phone number as Google provides it, usually in international format such as +15122411300 |
rating | Average star rating (number) |
category | Primary Google category, for example Real estate agency |
categories | All categories the business lists |
lat, lng | Coordinates |
place_id | Official Google Place ID (ChIJ...) |
timezone | IANA time zone of the business location |
photo | Cover photo URL, when Google has one |
domain | With enrich: host of the website, for example www.everydoorrealestate.com |
completeness | With enrich: share of six general fields that are filled (0-1). See the note below. |
Shared columns that stay empty for Google Maps data: price (null), price_text (empty), seller (empty), reviews (null) and description (empty). They exist because this Actor uses the same output core as our other scrapers. Filter them out in your export if you do not need them.
About completeness: it counts title, URL, price, location, seller and rating. Google Maps never provides price or seller for an agency, so the practical maximum here is 0.67. Use it to compare records within a run (a record at 0.33 is missing its website or rating), not as an absolute quality grade.
Summary row (last row of every run)
{"_summary": {"total_raw": 20,"total_clean": 20,"deduped": 0,"with_url": 17,"with_price": 0,"enriched": 0}}
The numbers above are illustrative; your run reports its own. If a query returns nothing, the summary carries a note field explaining that no results were found.
Changes row (monitor mode only)
{"_changes": ["ChIJc7oMZBS1RIYRx19u6pYyBAM", "ChIJOR9o-cBBkFQRR-k_PH6pJzc"]}
The list holds the Place IDs of records that were not present in the previous monitored run of the same query. The row is written only when there is at least one new record.
Table view
The Results view in the Dataset tab shows title, phone, url, location, rating, category, place_id, lat and lng. Rows starting with _summary or _changes are run metadata; filter them out when you import the data elsewhere.
Pricing
Pay per event, no subscription. Current prices are always shown on the Pricing tab; at the time of writing they are:
| Event | When it is charged | Price |
|---|---|---|
actor-start | Once per run | $0.0001 |
result | Per clean, de-duplicated business record | $0.002 |
enrichment | Per record enriched (only when enrich is on) | $0.01 |
change-alert | Per new record since the previous run (only when monitor is on) | $0.005 |
Duplicates are merged before the per-record charge, so you never pay twice for the same business in one run. A query that finds nothing costs only the start fee.
Worked examples
| Scenario | Events | Cost |
|---|---|---|
| One city, 20 agencies | 1 start + 20 results | $0.0001 + $0.04 = $0.0401 |
Same run with enrich | + 20 enrichments | $0.0401 + $0.20 = $0.2401 |
| 10 neighborhood queries, 20 agencies each | 10 starts + 200 results | $0.001 + $0.40 = $0.401 |
| First monitored run, 20 agencies (baseline) | 1 start + 20 results, no change alerts | $0.0001 + $0.04 = $0.0401 |
| Later weekly run, 20 agencies, 2 new | 1 start + 20 results + 2 change alerts | $0.0001 + $0.04 + $0.01 = $0.0501 |
The first monitored run of a query has no previous snapshot, so it only saves the baseline and charges no change alerts. From the second run on, only new agencies are reported and charged as change alerts.
Apify platform usage (compute, memory) for running the browser is billed by Apify according to your plan. Apify's free plan includes monthly platform credit, which is enough to test this Actor on real queries.
Integrations
API
curl -X POST "https://api.apify.com/v2/acts/enezli~realestate-agency-maps-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"query": "real estate agency Denver CO", "maxResults": 20}'
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_TOKEN")run = client.actor("enezli/realestate-agency-maps-scraper").call(run_input={"query": "real estate agency Denver CO", "maxResults": 20})agencies = [r for r in client.dataset(run["defaultDatasetId"]).iterate_items()if "_summary" not in r and "_changes" not in r]for a in agencies:print(a["title"], a.get("phone"), a.get("url"))
Schedules (scheduled change monitoring)
- Open the Actor, set your
queryand turn onmonitor. - Click Save as a new task and give it a clear name, for example "Boise agencies weekly".
- In Schedules, create a weekly schedule and add that task.
Each scheduled run compares its results with the previous monitored run of the same query. The comparison snapshot is stored per query in a named key-value store in your own Apify account (realestate-agency-maps-scraper-monitor), so several monitoring tasks with different queries do not interfere with each other. To be alerted, add an integration on the task (for example a webhook, Slack or email integration on run success) and read the _changes row.
n8n, Make, Zapier
Use the official Apify node or app: Run Actor (or Run Task) with this Actor, then Get dataset items. Skip items that contain _summary or _changes, and send the rest to Google Sheets, Airtable, HubSpot or your CRM. For monitoring flows, read the _changes row and look up the matching records by place_id.
AI agents (MCP)
This Actor is available through the Apify MCP server, so assistants such as Claude or Cursor can call it with a query and read back structured agency records.
Tips for best results
- Split big cities into neighborhoods or ZIP codes. One query returns up to about 20 businesses.
real estate agency 78704plusreal estate agency 78745covers more ground than one citywide query. - Use both "agency" and "realtor" wording. Google ranks brokerages and individual agents differently; running both queries gives a fuller picture. Merge the outputs by
place_id. - Keep one query per monitoring task. Monitoring compares runs of the same query; changing the query wording starts a new snapshot.
- Use
place_idas your key everywhere. Names change and websites are shared across franchise offices; the Place ID does not change. - Filter metadata rows. Remove rows with
_summaryor_changesbefore importing into a spreadsheet or CRM.
Limitations
- Up to about 20 businesses per query. The Actor reads one Google Maps results page and does not scroll or pan the map. For wider coverage, run several narrower queries.
- No review count. Google's search response includes the star rating but not the number of reviews, so
reviewsstays empty. - No emails and no agent names. Google Maps profiles do not list emails or staff, and this Actor does not visit agency websites. Use an email-finding or contact-enrichment tool on the
urlfield if you need them. - No opening hours, descriptions or photos gallery. Only the cover photo URL is returned.
- Not a property listing scraper. It does not return homes, rentals, prices or MLS data.
- No proxy rotation. The browser loads Google Maps directly. If Google shows a consent page or temporarily limits requests, a run can return no results; the summary then carries a note and you are charged only the start fee.
- Monitoring reports additions only. Businesses that disappear or change their details are not reported.
- Language of categories and addresses follows what Google serves. The Actor requests English, but Google may localize some fields.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
The run finishes with only a _summary row and a "No results" note | Query too narrow, or Google did not return results to this request | Broaden the query (city instead of street), or run it again later |
maxResults: 100 still returns about 20 | One query returns one results page | Run several narrower queries |
url is empty for some records | The business has no website on its Google Maps profile | Nothing to fix; this is useful as a signal |
| Categories or addresses in another language | Google localized the response | Add the country or state to the query; the Actor already requests English |
No _changes row on the first monitored run | The first run of a query only saves the baseline | Expected; from the next run on only new businesses are listed and charged |
FAQ
Do I need a Google API key or a Google Cloud billing account? No. The Actor uses a real browser against the public Google Maps website. No Google account or key is involved.
Does it scrape property listings like Zillow or Realtor.com? No. It returns real estate businesses (agencies, brokerages, agents) as they appear on Google Maps, not homes for sale or rent.
Can I use it for other business types? The Actor runs any query you give it, and the fields are the same for any business on Google Maps. It is built, documented and tested for real estate queries, which is where its defaults and table view make the most sense.
How do I get more than about 20 agencies for a city?
Run one query per neighborhood or ZIP code, then combine the datasets and de-duplicate by place_id.
How does change monitoring work?
With monitor on, the Actor stores the Place IDs of the current run under a key derived from your query, in a named key-value store in your account. The next monitored run of the same query compares against that list and writes the new Place IDs to a _changes row. You pay $0.005 per new business.
Will two offices of the same franchise be merged? No. Records are keyed by Google Place ID, so two branches that share a brand website stay separate.
Does it use AI? No. All fields come from Google's own response, and the processing is deterministic Python.
Are the phone numbers in international format?
They are returned as Google provides them, which is usually international format (for example +12062220531). The Actor does not add or guess country codes.
Is it legal to scrape Google Maps business data? The Actor collects publicly visible business information without logging in and without bypassing any access control. You are responsible for how you use the data, including Google's terms and local rules on marketing calls, texts and emails (for example GDPR in the EU or TCPA in the US).
I found a bug or need a field. Open an issue on the Issues tab. Requests that include the query you ran are the fastest to reproduce.
Trademarks
This Actor is not affiliated with, endorsed by, or connected to Google Maps. All product names are trademarks of their respective owners.