Every place Google Maps lists for one or more searches, as rows: name, rating, review count, address, phone, website, categories, opening hours, coordinates and Google's Place ID. Deduplicated on the Place ID and written to a CSV.
One Google Maps search stops at somewhere past a hundred places, the same point where Maps itself stops scrolling. To get more, split the search by area. These scripts call Google Maps Scraper with as many searches as you give them and merge the places they return.
The write-up, with a real run on coffee shops in Austin, is How to get past the Google Maps results limit.
You need an Apify account and its API token, from Console → Settings → API & Integrations.
Node (18 or newer):
cd node
npm install
APIFY_TOKEN=your_token node places.mjs "coffee shops in east austin tx" "coffee shops in south austin tx"Python (3.11 or newer):
cd python
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
APIFY_TOKEN=your_token python places.py "coffee shops in east austin tx" "coffee shops in south austin tx"Each search asks for every place Google lists (maxPlaces 200); set
MAX_PLACES=20 for a quick, cheap test. Both scripts print the rows per search
and write places.csv with one row per distinct place:
20 coffee shops in hyde park austin tx
20 coffee shops in north loop austin tx
40 rows from 2 search(es), 28 distinct places -> places.csv
Put the place in each search, the way you'd type it into Maps:
plumbers in east denver co, hotels in lisbon. A search without a place is
answered for wherever Google thinks the request came from.
sample-output.json holds four real rows: a place with
everything filled in, one with no website, phone or hours on its listing, one
with no reviews, and one from a "north austin" search whose address is in
Cedar Park. The fields you will use most:
| Field | What it holds |
|---|---|
name, address, phone, website |
As the Maps listing shows them; null when the listing has none |
rating, reviewCount |
Star rating and number of reviews |
categories, category |
Every category Google files the place under, and the primary one |
openingHours |
Hours by weekday |
latitude, longitude |
Coordinates |
placeId |
Google's Place ID; deduplicate across searches and runs on it |
position, page, query |
Google's rank for the search, the request it arrived on, and the search itself |
A search that could not be read comes back as a row with type: "error", an
error code and an errorDescription, and the run stays green. Both scripts
print those rows.
$0.0005 per place returned, Apify's platform costs included. The city-wide Austin search was 153 places, $0.08; the six neighbourhood searches were 681 rows, $0.34. A place that two searches both return is two rows and is charged twice: 219 of those 681 rows were repeats.
- One search stops at roughly 120–140 places for most searches (153 for Austin coffee shops). Split by area for more.
- Overlapping searches return the same place more than once, and each row is
charged. Deduplicate on
placeId. - The place in a search is a direction, not a boundary: 11 of 471 Austin places had an address in a neighbouring town.
- Google returns what it thinks matches. Check
categoriesbefore counting. - Reviews themselves are not included, only the rating and the count.

