Google Maps Review Opportunity Finder avatar

Google Maps Review Opportunity Finder

Pricing

from $4.80 / 1,000 review-opportunity-results

Go to Apify Store
Google Maps Review Opportunity Finder

Google Maps Review Opportunity Finder

Find local businesses on Google Maps that show review-growth or reputation-management opportunities, such as low review count, weak rating, missing review momentum signals, or under-reviewed competitors in a category/location.

Pricing

from $4.80 / 1,000 review-opportunity-results

Rating

0.0

(0)

Developer

Delowar Munna

Delowar Munna

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Google Maps Review Opportunity Finder

Find local businesses on Google Maps that show review-growth or reputation-management opportunities — low review counts, weak ratings, missing review momentum, or under-reviewed competitors in a category/location. Returns a clean, flat, CSV-friendly row per business with a transparent review opportunity score, opportunity tags, and a recommended pitch angle ready for outreach.

V1 deliberately avoids full review text scraping, reviewer profiles, owner responses, photos, AI generation, and website crawling so the run stays fast and cheap. You only pay for unique opportunity rows that pass your filters and are successfully written to the dataset.

✨ Why this scraper

  • Built for review/reputation outreach — 25 flat fields tuned for review generation, local SEO, and Google Business Profile improvement leads.
  • Transparent opportunity scoring — rule-based 0–100 score with reason tags and a recommended pitch angle. No AI, no black box.
  • Pay-Per-Event$ per saved unique opportunity row. Duplicates, filtered rows, and failed pushes are not charged.
  • No login, no cookies, no sessions — just keyword + location.
  • CSV-friendly output — flat structure, no nested objects, drops cleanly into Sheets/Excel/CRMs.

🚀 Quick start — sample inputs

Example 1 — single query, default opportunity score gate

{
"searchQueries": [{ "key": "plumbers", "value": "Canberra ACT" }],
"maxResults": 100,
"country": "AU",
"language": "en",
"minOpportunityScore": 25,
"opportunityMode": "balanced",
"maxRating": 4.2,
"maxReviewCount": 30,
"minRating": 0,
"minReviewCount": 0,
"websiteFilter": "any",
"phoneRequired": false,
"categoryFilter": "",
"includeCoordinates": true,
"deduplicateResults": true,
"proxyConfiguration": { "useApifyProxy": true }
}

Example 2 — multi-query, reputation-risk hunt (low-rating, phone required, has website to fix)

{
"searchQueries": [
{ "key": "dentists", "value": "Melbourne VIC" },
{ "key": "electricians", "value": "Sydney NSW" },
{ "key": "cafes", "value": "Brisbane QLD" }
],
"maxResults": 200,
"country": "AU",
"language": "en",
"minOpportunityScore": 50,
"opportunityMode": "reputationRisk",
"maxRating": 3.9,
"maxReviewCount": 100,
"minRating": 0,
"minReviewCount": 5,
"websiteFilter": "hasWebsite",
"phoneRequired": true,
"categoryFilter": "",
"includeCoordinates": true,
"deduplicateResults": true,
"proxyConfiguration": { "useApifyProxy": true }
}

The searchQueries field uses Apify's Key/Value form editor — the Key column is the business keyword (e.g. plumbers), the Value column is the location (e.g. Canberra ACT). Add one row per search.


📦 Output

The dataset has one view: Review opportunities — a 25-column flat table.

Review opportunities table view

Sample record — Review opportunities

{
"search_keyword": "electricians",
"search_location": "New York",
"business_name": "Nair Electric Corp",
"category": "Electrician",
"rating": 3,
"review_count": 4,
"phone": "718) 323-1408",
"website": "https://nairelectric.com/contact-us/",
"website_domain": "nairelectric.com",
"address": "266 Smith St",
"city": "New York",
"state": "",
"postcode": "",
"country": "",
"google_maps_url": "https://www.google.com/maps/place/Nair+Electric+Corp/data=!4m7!3m6!1s0x89c25a50b6173cd7:0xa65ef26c98ffef52!8m2!3d40.6827888!4d-73.9933416!16s%2Fg%2F11rghq418b!19sChIJ1zwXtlBawokRUu__mGzyXqY",
"place_id": "0x89c25a50b6173cd7:0xa65ef26c98ffef52",
"latitude": 40.6827888,
"longitude": -73.9933416,
"has_website": true,
"has_phone": true,
"review_opportunity_score": 80,
"review_opportunity_label": "High Review Opportunity",
"review_opportunity_tags": [
"very_low_review_count",
"under_reviewed_business",
"low_rating",
"has_phone",
"has_website",
"complete_address",
"review_generation_opportunity",
"reputation_opportunity",
"local_seo_opportunity"
],
"recommended_pitch_angle": "Review generation opportunity",
"scraped_at": "2026-05-08T06:35:15.076Z"
}

Output fields (25)

search_keyword, search_location, business_name, category, rating, review_count, phone, website, website_domain, address, city, state, postcode, country, google_maps_url, place_id, latitude, longitude, has_website, has_phone, review_opportunity_score, review_opportunity_label, review_opportunity_tags, recommended_pitch_angle, scraped_at.


🎯 Review opportunity score

Transparent rule-based score (0–100) computed from visible fields — no AI, no external enrichment. Higher score = stronger review/reputation opportunity.

Base formula

SignalPoints
Review count missing+25
Review count < 10+30
Review count 10–29+20
Review count 30–49+10
Rating missing+15
Rating < 3.5+30
Rating 3.5–3.9+20
Rating 4.0–4.2+10
Has phone+10
Has website+5
Complete address+5

Score is capped at 100.

opportunityMode adjustments

opportunityMode adds a bonus on top of the base score (no extra scraping needed):

ModeAdjustment
balancedDefault formula only.
lowReviews+15 if review count missing or < maxReviewCount.
lowRating+15 if rating missing or <= maxRating.
reputationRisk+20 if rating missing or < 3.8.
underReviewed+20 if review count missing or < 10.

Labels

ScoreLabel
75–100High Review Opportunity
50–74Medium Review Opportunity
25–49Low Review Opportunity
0–24Opportunity Not Clear

Derived from the highest-priority opportunity tag:

Top opportunityPitch angle
very_low_review_countReview generation opportunity
low_review_countReview growth opportunity
low_ratingReputation improvement opportunity
rating_missingProfile trust-building opportunity
under_reviewed_businessLocal SEO and review growth opportunity

Tag vocabulary

very_low_review_count, low_review_count, moderate_review_count, rating_missing, low_rating, average_rating, under_reviewed_business, review_generation_opportunity, review_growth_opportunity, reputation_opportunity, profile_trust_opportunity, local_seo_opportunity, has_phone, missing_phone, has_website, missing_website, complete_address, missing_address.


💰 Pricing

Pay-Per-Event. The actor charges a single review-opportunity-result event for each unique, filtered opportunity row that is successfully written to the dataset. The actor honors the user-configured per-run spending cap (Apify eventChargeLimitReached) and stops cleanly when reached.

Not charged:

  • Duplicates (de-duplicated by place_id, listing URL, or name+address).
  • Rows filtered out by minOpportunityScore, maxRating, maxReviewCount, minRating, minReviewCount, websiteFilter, phoneRequired, or categoryFilter.
  • Rows missing a business_name.
  • Failed dataset pushes.
  • Anything after the per-run spending cap is reached.

🚦 Proxy policy

Use Apify Datacenter proxy or no proxy for normal runs — both work reliably for Google Maps search at this actor's conservative concurrency (max 3).

Apify Residential proxy is not supported. The actor will fail at startup if apifyProxyGroups includes RESIDENTIAL. Reason: in pay-per-event actors, residential bandwidth ($8/GB) is billed to the developer, not the run user, so a single bandwidth-heavy run could exceed the per-result event revenue.

If you genuinely need residential routing (rare for Maps search), supply your own residential provider via the proxy editor's Custom proxy URLs field — that traffic goes through your provider, not Apify, and is unaffected:

http://user:pass@proxy.brightdata.com:22225
http://user:pass@proxy.oxylabs.io:7777

📊 Run summary

After each run, a RUN_SUMMARY entry is written to the key-value store:

{
"inputs_total": 3,
"successful_inputs": 3,
"failed_inputs": 0,
"raw_results_found": 240,
"results_saved": 100,
"duplicates_removed": 20,
"filtered_out": 120,
"charged_events": 100,
"blocked_requests": 0,
"retry_count": 3,
"runtime_seconds": 180,
"scraped_at": "2026-05-06T00:00:00.000Z"
}

charged_events always equals results_saved.


⚙️ Filters

FilterEffect
minOpportunityScoreDrop rows whose review opportunity score is below this value (0 disables).
maxRatingDrop rows with a rating above this. Missing rating is kept (opportunity).
maxReviewCountDrop rows with more reviews than this. Missing review count is kept (opportunity).
minRatingDrop businesses below this star rating (0 disables; missing rating is dropped).
minReviewCountDrop businesses with fewer reviews (0 disables; missing review count treated as 0).
websiteFilterany / hasWebsite / missingWebsite.
phoneRequiredIf true, keep only businesses with a visible phone.
categoryFilterCase-insensitive contains match against the business category.
deduplicateResultsDrop duplicates across queries (recommended ON).

Filters are applied after extraction and scoring and before dataset push or event charge.


🚧 Limitations (V1)

  • Cards-only extraction: V1 reads each business row directly from the search results panel and does not click into individual place detail panels. Phone, website, full opening hours, and place_id only appear when Google surfaces them on the card itself; otherwise these fields are empty/null.
  • No full review text scraping, reviewer profiles, owner responses, or review photos.
  • No website crawling, email extraction, or social link extraction.
  • No AI-generated outreach messages or AI reputation summaries.
  • No login/cookie/session-based scraping.
  • Address parsing into city/state/postcode is best-effort; the full address field is the source of truth.
  • Per-query hard cap is 500 results; per-run hard cap is 5,000 results.

🛠️ Technical notes

  • Stack: Node.js 22 · Apify SDK 3 · Crawlee · Puppeteer.
  • Concurrency: min=1, max=3 (conservative to reduce blocking).
  • Memory: 1 GB min · 2 GB default · 4 GB max.
  • Proxy: Apify Proxy enabled by default; custom configs accepted. Recommended for most real runs.
  • Diagnostics: On the first failed render (no feed, or feed but zero cards), the actor saves the page HTML and URL to the key-value store as debug-no-feed-html / debug-zero-cards-html.