Google Maps collection
A Google Maps scraper that shows where every value came from.
Give it a list of keywords and a list of places. It searches Google Maps for every combination and returns one row per business, with the connector, the source and the time recorded against every field it stored.
Before anything else
- Source
- Google Maps listings
- Affiliation with Google
- None
- Access
- Operator-provisioned
NanoScraper is not affiliated with, endorsed by or sponsored by Google. Google Maps is named here as the source the connector reads.
Keywords, places, and the multiplication between them.
Two lists, one entry per line. Every keyword is run against every place, and each pairing is its own search.
Seven lines of typing, twelve searches
Keywords
- dentist
- dental practice
- orthodontist
Places
- Leeds
- Manchester
- Bristol
- Sheffield
Searches
12
Language, scroll depth, map zoom and a results cap are set alongside the two lists. The cap applies per collection.
One search at a time, at roughly thirty-five seconds.
Throughput is the binding constraint here, so it is the number quoted first rather than the one left out.
- 0135 sOne search, roughly, start to finish.
- 0210The most searches a single job accepts.
- 0312 minHow long the connector waits for one job, by default.
- 044 days100 keywords × 100 places — 10,000 searches.
Which is why a plan is not a job
A campaign is a named plan — your keywords by your places — that expands into many jobs and works through them on its own. One job cannot hold ten thousand searches, and four days is longer than any single run should live.
The work list is a table rather than a variable, because four days spans a redeploy, a dead worker and somebody pausing it. A sweep every ninety seconds does at most one thing per campaign, so nothing races ahead.
One row per business.
Not one row per page read, and not one per time a business was seen. These are the columns the export actually carries, in order. Two of them arrive empty from this source, and the file says which rather than looking complete.
- 01Name
- 02Domain
- 03Website
- 04Phone
- 05Languagenever filled from this source
- 06Descriptionempty in every row measured
- 07Category
- 08Address
- 09Latitude
- 10Longitude
- 11Rating
- 12Review count
- 13Opening hours
- 14Listing URL
- 15Place ID
- 16CID
Found twice, stored once
Two searches that both return the same business produce one record, updated in place. Matching runs on the identifier the listing itself carries, so a business that renames itself or is spelled differently in two languages still matches.
A business with no website keeps an empty website. Borrowing the listing address instead once merged unrelated companies into one, because every listing shares a single host — and it asserted a site the source never claimed.
Two identifiers, and they are not interchangeable
CID
3669834603025597947
The number in a maps.google.com/?cid= link. Identity is derived from this.
Place ID
ChIJ…
The token the Google Places API accepts. Kept under its own name, unchanged.
Both are kept, each under its own name. Storing one under the name of the other produces a column the Places API rejects.
Google Maps carries no email addresses, so nothing here invents them.
A Maps listing does not carry one, so the stored payload has no email key. The engine can be told to open each website and hunt for an address; this connector pins that off. A tool that hands you an email from a Maps listing went looking elsewhere for it.
Two fields, and only one of them exists
absent is not empty
A contact collected this way carries a phone number and no email address, because the listing it came from had no email address to carry.
A missing value stays blank. Nothing is borrowed from another record and nothing is guessed, because an invented fragment in the evidence table is worse than an empty one.
Every value keeps the observation behind it.
Field by field, not record by record. Different fields on one business routinely come from different observations, and collapsing that would assert one source produced the whole row.
Four exports on companies
CSV
The records the current filters select, one row each.
Excel
The same rows and the same columns, as a workbook.
Evidence CSV
One row per stored piece of evidence, not one per business.
Excel + evidence
Two sheets, Records and Evidence, joined on Record ID.
What the evidence file carries
- 01Record ID
- 02Company
- 03Field
- 04Stored value
- 05As observed
- 06Connector
- 07Connector version
- 08Source
- 09Observed at
As observed is what the source said before it was normalised. It is legitimately blank when nothing distinct was stored — a phone number the listing already printed in the stored form has no second version.
How the raw observation and the canonical record stay separate is set out in where every value came from, and the collection path itself in how collection works.
Three things this cannot tell you.
Each is a property of what the source publishes, written down here rather than discovered after the first export.
- 01Which search found a business
- The engine tags each batch of rows with a random identifier and publishes no mapping back to the keyword. “This one came from Lyon” is not something this pipeline can say, so counts belong to the batch rather than the search.
- 02Whether a listing is true
- What is recorded is what the listing published and when it was read. Whether a phone number still reaches the business is not knowable from inside NanoScraper, and nothing here estimates it.
- 03Everything a search could return
- Scroll depth bounds how far each result list is read, and the results cap applies per collection, not per search. A run returns what it reached inside those two numbers, and both are yours to set.
The other sources, briefly
Google Maps is one connector of four. The others read a page you name, parse markup, or reach a separately run service over HTTP. All of them sit behind the same boundary and produce observations in the same shape.
The collection here is real and it is small: a few hundred businesses. Nothing on this page describes a volume that has been run.
Ask for an account and start collecting.
Access is provisioned by the operator; there is no self-service registration. Tell us what you want to collect and where. A person reads it — there is no automatic reply, and no response time is promised here that does not exist.
NanoScraper is not affiliated with, endorsed by or sponsored by Google. Google and Google Maps are trademarks of their respective owner, named here only as the source this connector reads.