Google Maps Phone Scraper
Under maintenancePricing
from $1.00 / 1,000 results
Google Maps Phone Scraper
Under maintenanceExtract public phone numbers from Google Maps businesses based on your search queries. Automatically normalizes numbers to international E.164 format, removes duplicates, and filters by rating or category. Export clean data to JSON, CSV, or Excel.
Pricing
from $1.00 / 1,000 results
Rating
5.0
(1)
Developer
NodeFlow
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
Google Maps Phone Scraper is a focused Apify Actor that finds businesses for one or more Google Maps searches and saves only businesses with a public phone number. Phone numbers are normalized to international E.164 format, and duplicate places or duplicate phone numbers are removed across the whole run.
What it does
- Searches Google Maps with your query, city, and country.
- Opens business detail pages concurrently.
- Uses DOM-readiness checks and automatic navigation retries instead of waiting for Google Maps to finish every background request.
- Skips every business without a public, usable phone number.
- Normalizes national numbers with the selected country's calling code (for example,
(212) 555-1234becomes+12125551234). - Removes duplicates by Google place identity and normalized phone number.
- Optionally filters by minimum rating and category text.
- Writes clean JSON, CSV, Excel, XML, or other formats through the Apify dataset export API.
The Actor reads only information shown publicly on Google Maps. It does not sign in, bypass access controls, or collect private contact data.
Input
| Field | Type | Required | Description |
|---|---|---|---|
searchQueries | string[] | Yes | Business searches such as dentists or coffee shops. |
city | string | No | City/locality appended to each query. |
country | string | No | ISO alpha-2 code or English/Turkish country name. Also controls phone parsing. Default: US. |
maxResults | integer | Yes | Run-wide cap for unique phone-bearing businesses, from 1 to 500. |
minRating | number | No | Minimum rating from 0 to 5. Unrated places are excluded if greater than 0. |
categoryFilter | string | No | Case-insensitive substring matched against the displayed category. |
language | string | No | Two-letter Google Maps UI language. Default: en. |
maxConcurrency | integer | No | Parallel detail pages, from 1 to 8. Default: 3. |
proxyConfiguration | object | No | Apify Proxy configuration. Recommended on the platform; disable for local tests. |
Example input
{"searchQueries": ["dentists","orthodontists"],"city": "New York","country": "US","maxResults": 25,"minRating": 4.5,"categoryFilter": "dental","language": "en","maxConcurrency": 3,"proxyConfiguration": {"useApifyProxy": true}}
maxResults is a cap, not a guarantee. A run can return fewer records when Google Maps has fewer matching businesses with public phone numbers, filters remove candidates, or Google limits access.
Output
Each dataset row has the same shape. Optional source fields that are not displayed by Google Maps are null or an empty string.
{"businessName": "Example Dental Clinic","phone": "+12125551234","address": "123 Main Street, New York, NY 10001","city": "New York","country": "US","category": "Dental clinic","website": "https://example.com/","rating": 4.8,"reviewCount": 125,"googleMapsUrl": "https://www.google.com/maps/place/...","searchQuery": "dentists"}
The phone field is always a usable international number beginning with +. A row is never written if its phone number cannot be normalized.
Run locally
Requirements: Node.js 22 or newer.
npm installnpx playwright install chromium
Create storage/key_value_stores/default/INPUT.json:
{"searchQueries": ["dentists"],"city": "New York","country": "US","maxResults": 5,"proxyConfiguration": { "useApifyProxy": false }}
Then run:
$npm start
Results are written to storage/datasets/default/ in local mode.
Tests
npm testnpm run test:live
The unit suite checks input validation, country resolution, E.164 normalization, duplicate keys, numeric parsing, and filters. The live suite performs a real Google Maps search and verifies that at least one returned business has a valid E.164 phone. Because the live test depends on an external website, its result can vary with network location, consent screens, rate limits, and Google UI changes.
Reliability and responsible operation
- Keep concurrency conservative. A value of 2-4 is normally sufficient; higher values can trigger rate limits without improving throughput.
- Use Apify Proxy for cloud runs and choose a proxy location consistent with the target country when appropriate.
- Each run creates a fresh sticky proxy session, avoiding accidental reuse of a previously throttled session while keeping one stable IP inside the browser run.
- Google Maps is an external website and can change its interface. Monitor empty runs and update selectors when necessary.
- Do not use output for spam, harassment, unlawful profiling, or automated calling that violates consent and do-not-call rules.
- Respect privacy, database, consumer-protection, marketing, and telecommunications laws in every affected jurisdiction.
Google Maps data responsibilities
Google controls access to and permitted use of Google Maps content. Automated extraction, storage, reuse, and creation of business or telephone-listing databases may be restricted by the Google Maps/Google Earth Additional Terms and the applicable Google Maps Platform Terms. These terms and local laws can change.
Before running this Actor, you are responsible for confirming that your intended collection, retention, export, and use are lawful and permitted, obtaining any required authorization, honoring deletion/opt-out requests, and applying appropriate retention and security controls. Public availability of a phone number does not by itself grant permission for every downstream use. This project is a technical tool, not legal advice, and is not affiliated with or endorsed by Google.
Limitations
- Only phone numbers visible on Google Maps detail pages are returned.
- The category filter matches Google's displayed category text; it is not a taxonomy lookup.
cityandcountrydescribe the requested search scope. Google can occasionally show nearby places outside that scope.- Google may show localized or experiment-specific layouts, consent pages, or anti-bot challenges.
- A business that shares a phone number with another listing appears only once by design.
