Google Search Results Scraper with Local Businesses
Pricing
$19.99/month + usage
Google Search Results Scraper with Local Businesses
🔎 Google Search Results Scraper extracts live SERP data—titles, snippets, URLs, rankings, ads & featured snippets—by location, language and device. ⚙️ Built for SEO, keyword research, competitor analysis & content planning. 🚀 Fast, scalable, proxy-ready.
Pricing
$19.99/month + usage
Rating
0.0
(0)
Developer
ScraperForge
Maintained by CommunityActor stats
0
Bookmarked
16
Total users
3
Monthly active users
7 days ago
Last modified
Categories
Share
Google Search Results Scraper with Local Businesses — SERP Data + the Google Maps Places Pack
Scrape live Google Search results — organic listings, ads, People Also Ask, related queries, AI Overview and result counts — and the local "Places" business pack that appears for local-intent queries, with name, rating, category, address, phone, website, hours and directions link.
Standard SERP JSON output, 240+ country domains, UULE-precise location targeting, and optional AI-search add-ons for answer-engine optimisation.
What is Google Search Results Scraper with Local Businesses?
Most SERP scrapers give you the ten blue links. This one also captures the thing local businesses actually care about: the map pack.
Search Google the same way you would in a browser — a keyword, a full Google search URL, or advanced operators — and the Actor returns a standard SERP object (searchQuery, organicResults, paidResults, peopleAlsoAsk, relatedQueries, aiOverview) plus a localResults array containing the business pack for local-intent queries.
Crucially, the local pack goes deeper than the three businesses Google shows inline: raise maxLocalResults and the Actor also fetches the paginated "More places" finder page, turning a three-result box into a proper local business list.
What data can you extract?
Search results
| Field | Description |
|---|---|
searchQuery | Term, URL, device, page, domain, country, language, UULE, results-per-page |
organicResults | Ranked organic listings |
paidResults, paidProducts | Google Ads and shopping-style paid results |
peopleAlsoAsk | PAA questions surfaced for the query |
relatedQueries, suggestedResults | Related search suggestions |
aiOverview | Google's AI Overview, when enabled |
resultsTotal | Total result count Google reports |
hasNextPage, serpProviderCode | Pagination and provider metadata |
htmlSnapshotUrl, html | Raw HTML snapshot, when saving is enabled |
Local business pack (localResults[])
| Field | Description |
|---|---|
position, isAd | Rank within the pack, and whether it is a paid placement |
title | Business name |
rating, reviewsText, reviewsAriaLabel | Star rating and review counts |
category | Business category |
priceRange | Price band |
address, cityState | Location |
phone | Contact number |
website | Business website |
openStatus, openDetail | Open/closed status and hours detail |
yearsInBusiness | Longevity signal |
scheduleUrl, directionsUrl | Booking and directions links |
mapsFeatureId | Google Maps feature identifier |
attributes | Business attributes shown in the pack |
reviewSnippet | Featured review text |
source | Whether the entry came from the inline pack or the "More places" list |
Plus hasLocalPack, localPackHeading, localSearchLocation and localFinderUrl at the query level.
Why teams scrape Google SERPs and the local pack
For local SEO agencies
The map pack is where local search traffic actually goes, and it is invisible to most rank trackers. Scraping it per keyword and per location tells you exactly who occupies positions 1–3, with their rating, review count and category — which is the whole competitive picture in local search.
For local lead generation
Every local pack entry carries a phone number and website. A keyword like plumber in austin tx becomes a qualified contact list, and minLocalRating lets you target either the strong performers or the businesses with reputation problems.
For keyword and content research
peopleAlsoAsk and relatedQueries are Google telling you what else the searcher wants to know — the fastest legitimate route to a content outline that matches real search intent.
For rank tracking
organicResults with positions, run on a schedule with a fixed locationUule, gives you a defensible ranking history for any keyword set and market.
For answer-engine optimisation (AEO/GEO)
With the AI add-ons enabled you can compare how Google AI Mode, Perplexity and ChatGPT Search answer the same query — which sources each cites, and where your brand is absent. That cross-platform comparison is the current frontier of search visibility work.
For ad and competitor intelligence
paidResults and paidProducts show who is bidding on your keywords, and the paid-ads add-on improves detection accuracy with an ad-specialised proxy and retries.
How to scrape Google search results step by step
- Open the Actor and enter your search terms — one per line. Full Google search URLs work too.
- Set Max pages per search. Roughly 1 page ≈ 10 results, so 10 pages ≈ 100 results.
- Leave Extract local business pack on for local-intent keywords, and set Max local businesses per query.
- Set Country, Interface language and, for precise local work, a UULE location code.
- Click Start, then export the Output tab as JSON (recommended — the SERP object is nested).
⬇️ Input
Example input — local SEO
{"queries": "plumber in austin tx\nemergency plumber austin","includeLocalPack": true,"maxLocalResults": 20,"minLocalRating": 4,"countryCode": "us","languageCode": "en","maxPagesPerQuery": 1}
Example input — organic rank tracking
{"queries": "best crm software\ncrm for small business","includeLocalPack": false,"maxPagesPerQuery": 3,"resultsPerPage": 100,"countryCode": "gb","locationUule": "<UULE_CODE>"}
Input reference — local pack
| Field | Type | Default | Description |
|---|---|---|---|
includeLocalPack | boolean | true | Capture the local/map "Places" box into localResults. Requires not restricting to the Web-only tab, so enabling it omits the udm=14 restriction the base behaviour applies when AI Mode is off. |
maxLocalResults | integer | 20 | Local businesses per query. 0 = unlimited. 3 or fewer uses only the inline pack (no extra request); higher values also fetch the paginated "More places" finder page. |
onlyQueriesWithLocalPack | boolean | false | Drop a query's row entirely — not pushed, not charged — when no local pack was found. Ideal for triaging a keyword list down to genuinely local terms. |
minLocalRating | number | 0 | Drop businesses rated below this threshold (0–5). Businesses with no rating are always kept. |
Input reference — search
| Field | Type | Default | Description |
|---|---|---|---|
queries | string | — (required) | Search terms or Google search URLs, one per line. Supports operators such as site:, OR, AND. Keep each query under 32 words (a Google limit). |
resultsPerPage | integer | 100 | Passed to Google as num. Google applies its own filtering, so actual counts vary — especially on page 1. |
maxPagesPerQuery | integer | 1 | Pages per query; each page ≈ 10 results. |
mobileResults | boolean | — | Return mobile SERPs instead of desktop. |
includeUnfilteredResults | boolean | — | Ask Google to include results it would normally filter out. |
includeIcons | boolean | — | Include result icons. |
saveHtml / saveHtmlToKeyValueStore | boolean | — | Keep the raw HTML in the dataset row or in the key-value store. |
Input reference — location and language
| Field | Type | Default | Description |
|---|---|---|---|
countryCode | string | us | Search country and Google domain (240+ options; e.g. es → google.es). |
searchLanguage | string | — | Restrict results to pages in a language (lr parameter). |
languageCode | string | en | Interface language (hl parameter). |
locationUule | string | — | Exact location via Google's UULE parameter — the reliable way to emulate a specific local search. |
Input reference — advanced filters
forceExactMatch, site, relatedToSite, wordsInTitle, wordsInText, wordsInUrl, quickDateRange, beforeDate, afterDate, fileTypes.
Note:
sitetakes precedence overrelatedToSite. If both are set,relatedToSiteis ignored.
Input reference — paid add-ons ($)
| Field | Description |
|---|---|
aiMode | aiModeOff, aiModeWithSearchResults or aiModeOnly — scrape Google AI Mode for AEO and brand-visibility work. |
serpApiKey | Optional SerpApi key to fetch AI Overview when AI Mode is active. |
perplexitySearch | Perplexity Sonar answers and citations, with recency, images and related-questions options. |
chatGptSearch | ChatGPT Search answers, including query fan-out. |
focusOnPaidAds | Ad-specialised proxy with up to 3 retries per query for better ad detection. Costs extra per search page whether or not ads are found. |
maximumLeadsEnrichmentRecords | Leads per domain — names, titles, e-mails, phones, LinkedIn and company data. 0 disables it. |
leadsEnrichmentDepartments | Restrict enrichment to departments (Sales, Marketing, C-Suite…). Only applies when leads enrichment is enabled. |
Add-ons marked ($) carry additional cost. They are opt-in and disabled by default — check the Pricing tab before enabling them at scale.
⬆️ Output
Example output (trimmed)
{"searchQuery": {"term": "plumber in austin tx","url": "https://www.google.com/search?q=plumber+in+austin+tx","device": "DESKTOP","page": 1,"domain": "google.com","countryCode": "US","languageCode": "en","resultsPerPage": 100},"searchQueryTerm": "plumber in austin tx","resultsTotal": 18400000,"hasLocalPack": true,"localPackHeading": "Places","localSearchLocation": "Austin, TX","localFinderUrl": "https://www.google.com/search?…&udm=1","localResults": [{"position": 1,"isAd": false,"title": "Example Plumbing Co.","rating": 4.8,"reviewsText": "412 reviews","category": "Plumber","address": "142 Example St","cityState": "Austin, TX","phone": "+1 512-555-0142","website": "https://exampleplumbing.com","openStatus": "Open","openDetail": "Closes 6 PM","yearsInBusiness": "12 years in business","scheduleUrl": "https://exampleplumbing.com/book","directionsUrl": "https://www.google.com/maps/dir/…","attributes": ["Onsite services", "Emergency service"],"reviewSnippet": "Fast, honest and fixed it first time.","source": "localPack"}],"organicResults": [{ "position": 1, "title": "Austin Plumbers | Example Directory", "url": "https://example-directory.com/austin" }],"paidResults": [],"peopleAlsoAsk": [{ "question": "How much does a plumber cost in Austin?" }],"relatedQueries": [{ "title": "24 hour plumber austin", "url": "https://www.google.com/search?q=…" }]}
Illustrative values — a live run returns current Google data.
Usage recipes
Build a local lead list
{"queries": "plumber in austin tx\nhvac repair austin tx\nelectrician austin tx","includeLocalPack": true,"maxLocalResults": 0,"onlyQueriesWithLocalPack": true}
maxLocalResults: 0 pulls everything Google exposes including the "More places" list, and onlyQueriesWithLocalPack means you are not charged for keywords that turn out not to be local.
Triage a keyword list for local intent
Run your whole keyword list with onlyQueriesWithLocalPack: true and a small maxLocalResults. What survives is the subset worth optimising for local SEO.
Target only strong or weak competitors
{"queries": "dentist manchester","minLocalRating": 4.5,"maxLocalResults": 20}
Raise the threshold to study winners; leave it at 0 and filter the export for low ratings to find reputation-management prospects.
Rank tracking with precise location
{"queries": "best crm software","includeLocalPack": false,"maxPagesPerQuery": 3,"locationUule": "<UULE_CODE>","countryCode": "gb"}
Schedule it and store organicResults positions over time.
Content brief generation
Run your target keyword and read peopleAlsoAsk plus relatedQueries. That is Google's own map of the topic.
Cross-platform AEO comparison
Enable aiMode, perplexitySearch and chatGptSearch on the same query set and compare which sources each engine cites. Gaps where competitors appear and you do not are your AEO backlog.
How does this compare to Google's official APIs?
Google's Custom Search JSON API is limited to a Programmable Search Engine, returns a restricted result set, is capped at 100 queries per day free, and does not return the local pack, ads, People Also Ask or AI Overview. The Places API returns business data but is a separate paid product with its own quotas and licensing restrictions, and it does not tell you ranking — which business appears first for a given search, from a given location.
This Actor reads the actual SERP a user sees, which is the only way to capture ranking positions, the map pack in ranked order, ads and SERP features together in one record.
Integrate and automate
Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_API_TOKEN>")run = client.actor("scraperforge/google-search-results-scraper").call(run_input={"queries": "plumber in austin tx","includeLocalPack": True,"maxLocalResults": 20,})for page in client.dataset(run["defaultDatasetId"]).iterate_items():for biz in page.get("localResults", []):print(biz["position"], biz["title"], biz.get("rating"), biz.get("phone"), biz.get("website"))
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_API_TOKEN>' });const run = await client.actor('scraperforge/google-search-results-scraper').call({queries: 'plumber in austin tx',includeLocalPack: true,maxLocalResults: 20,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
REST API
curl -X POST "https://api.apify.com/v2/acts/scraperforge~google-search-results-scraper/runs?token=<YOUR_APIFY_API_TOKEN>" \-H "Content-Type: application/json" \-d '{"queries":"plumber in austin tx","includeLocalPack":true,"maxLocalResults":20}'
n8n, Make, Zapier and AI agents
Call the Actor from n8n, Make, Zapier or an MCP-capable agent — a natural fit for weekly rank reports or an agent that researches a local market on demand.
Schedules and webhooks
Attach a Schedule for recurring rank and map-pack tracking, and use webhooks or the Google Sheets / Airtable / Slack / Google Drive integrations to route results into reporting.
Pricing and what you are charged for
This Actor is offered on a monthly rental basis, and usage is calculated on the number of pages navigated — the working formula is 1 page ≈ 10 results, so ~100 results means maxPagesPerQuery: 10.
Cost-relevant behaviours worth knowing:
onlyQueriesWithLocalPack: truedoes not charge for dropped rows — queries without a local pack are skipped entirely.maxLocalResultsof 3 or fewer needs no extra request (inline pack only). Higher values trigger the additional "More places" fetch.- Add-ons marked ($) — AI Mode, Perplexity, ChatGPT Search, paid-ads extraction and leads enrichment — carry additional per-result or per-page fees, and
focusOnPaidAdscharges per search page whether or not ads are found.
Current rates and add-on pricing are on the Pricing tab of this Actor's page.
Limits, reliability and blocking
- Google filters
resultsPerPageitself. Asking for 100 does not guarantee 100, especially on page 1. UseincludeUnfilteredResultsto push closer to your target. - Keep queries under 32 words — that is Google's limit, not the Actor's.
- Local pack requires the non-Web-only tab. Enabling
includeLocalPackremoves theudm=14restriction; if you specifically want Web-only results, turn the local pack off. minLocalRatingnever drops unrated businesses — only those with a rating below your threshold.siteoverridesrelatedToSitewhen both are set.- UULE is the reliable way to emulate a location. Country code alone changes the Google domain, not the searcher's precise position.
- SERPs are volatile. Positions, ads and SERP features change hour to hour; timestamp your runs for tracking work.
- Default run options are 4 GB memory and a 1-hour timeout; raise the timeout for large keyword sets with add-ons enabled.
Is it legal to scrape Google search results?
This Actor reads publicly displayed search results — the same page any visitor sees, without logging in. Search rankings and business listings are factual observations about a public page.
Two things to be careful with. First, Google's terms restrict automated access, so keep volumes proportionate and do not resell raw SERP pages as a product. Second, the local business data and any leads enrichment output contain personal data — names, phone numbers, e-mail addresses. Processing those is subject to GDPR, CCPA/CPRA and comparable regimes: have a lawful basis, honour opt-outs, respect do-not-call registries, and comply with CAN-SPAM and local marketing rules before any outreach. You are responsible for ensuring your use complies with Google's terms and applicable law.
❓ Frequently asked questions
What makes this different from a normal SERP scraper?
The local business pack. Most SERP scrapers return organic links only; this one also extracts the map pack with ratings, phones, websites and hours — and can go beyond the three inline entries into the full "More places" list.
How many results do I get per page?
Roughly 10, which is why maxPagesPerQuery: 10 approximates 100 results. Google's own filtering means the exact count varies.
How do I search from a specific city?
Use locationUule with a generated UULE code. countryCode only changes the Google domain and country context.
Why did a query return no local results?
Because Google did not show a local pack for it — usually a non-local intent. Set onlyQueriesWithLocalPack: true to drop those rows and avoid paying for them.
Does minLocalRating remove businesses with no reviews?
No. Unrated businesses are always kept; only businesses whose rating is below your threshold are dropped.
What do the ($) add-ons cost?
They carry extra fees on top of the base usage — see the Pricing tab. AI Mode, Perplexity, ChatGPT Search, paid-ads extraction and leads enrichment are all opt-in and off by default.
Can I compare Google AI Mode with ChatGPT and Perplexity?
Yes — that is exactly what the AI add-ons are for. Enable them together and compare answers and citations for the same query.
Can I use Google search operators?
Yes — site:, OR, AND, intitle: and others work, and there are dedicated fields for site, related-site, words in title/text/URL, file types and date ranges.
Does it return ads?
Yes, in paidResults and paidProducts. Enable focusOnPaidAds for better detection accuracy, bearing in mind it costs extra per page.
Which export format should I use?
JSON. The output is a nested SERP object with localResults, organicResults and peopleAlsoAsk arrays; CSV flattens it awkwardly.
🔗 Related scrapers
- Leads Scraper — B2B contact database to enrich the domains you find in the SERP.
- Facebook Search Scraper — the same local businesses, from their Facebook pages.
- Realtor.com Agent Scraper — vertical-specific local professional data.
- Google Flights Scraper — another public Google surface, for travel pricing.
Browse the full collection on the ScraperForge profile.
💬 Feedback
Need deeper local-pack pagination, extra SERP features, or a custom rank-tracking pipeline? Open an issue on the Issues tab of this Actor.