Google Local Services Ads Scraper (LSA Lead Extractor) avatar

Google Local Services Ads Scraper (LSA Lead Extractor)

Pricing

from $8.20 / 1,000 searcheds

Go to Apify Store
Google Local Services Ads Scraper (LSA Lead Extractor)

Google Local Services Ads Scraper (LSA Lead Extractor)

Extract Google Local Services Ads (LSA) leads: business name, phone number, rating, reviews, badges, years in business and service area.

Pricing

from $8.20 / 1,000 searcheds

Rating

0.0

(0)

Developer

OptiRefine

OptiRefine

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 hours ago

Last modified

Share

Google Local Services Ads Scraper (LSA Extractor)

Extract Google Local Services Ads (LSA) provider listings — the "Google Guaranteed" cards with a call button at the top of local search results — as clean dataset rows. Point this Google Local Services Ads scraper at a service (plumbers, roofers, HVAC, electricians, house cleaners...) and a city, and it returns each provider's business name, call-tracking phone number, star rating, review count, trust badges, years in business and service area.

Google itself caps every search at 20 providers per service, per location — that's Google's own limit, not an actor setting; see How many results can I get?. Within that cap, this LSA scraper is built for lead generation agencies filling a pipeline of local businesses to pitch, local SEO consultants auditing who's winning the paid local pack in a market, and anyone doing competitor research on who is actively paying Google for calls in a city. It reads Google's own server-rendered results page over plain HTTP rather than driving a browser, which keeps runs fast and predictable on the Apify platform.

How do I scrape Google Local Services Ads?

  1. List the services in searchQueries — plain wording like plumbers or roofers returns more results than Google's formal category names.
  2. List the cities in locations, including state, province or country ("Austin, TX", not "Austin") so Google — and the proxy — picks the right country.
  3. Add a country-matched proxy in proxyConfiguration (residential recommended). Local Services Ads only render for visitors Google believes are in the same country as the search — see Why am I getting zero results?.
  4. Run the actor. Each service × location pair returns up to 20 providers as rows in the dataset, ready to export as CSV/JSON or pulled out over the Apify API.

What data you get

Each row in the output dataset is one advertiser from one search. Field names below match LsaProvider in the source exactly — use them as-is in your integration. For each field's exact null conditions and where it comes from in Google's markup, see the docs/OUTPUT-REFERENCE.md.

FieldTypeDescription
customerIdstring | nullGoogle's internal advertiser/customer ID. This is the only reliable way to tell two listings apart — two different advertisers can legitimately share the same business name.
namestring | nullBusiness name as shown on the ad card.
phonestring | nullPhone number in E.164 format, e.g. +14165550142. This is a Google call-tracking number that forwards to the business — see About the phone numbers.
phoneDisplaystring | nullThe number as printed in the card's visible text. Almost always null — Google shows a "Get phone number" button instead of the digits. Use phone; this is only a fallback.
phoneRegionCodestring | nullTwo-letter region code Google associates with the phone number, e.g. CA.
businessIdstring | nullGoogle's internal business ID for the listing.
providerIdstring | nullGoogle's internal provider ID for the listing.
ratingnumber | nullAverage star rating, e.g. 4.9. null when the provider has no reviews yet.
reviewsCountnumber | nullNumber of reviews behind the rating. null when the provider has no reviews yet.
providerTypestring | nullThe service category label Google prints on the card, e.g. Plumber.
yearsInBusinessTextstring | nullThe raw "years in business" line as Google renders it, e.g. 28+ years in business.
yearsInBusinessnumber | nullJust the number parsed out of the line above, e.g. 28.
serviceAreaTextstring | nullThe raw service-area line, e.g. Serves Whitby.
serviceAreastring | nullJust the place name, e.g. Whitby.
hoursstring | nullOpening-hours summary shown on the card, e.g. Open 24 hours or Open · Closes 8 PM.
isOpenNowboolean | nulltrue when the hours text indicates the business is open right now.
badgesstring[]Trust/verification badges Google shows, e.g. Google Guaranteed, Google Screened, Background checked.
highlightsstring[]Marketing highlights the business chose to display, e.g. Family owned, Flat rate pricing.
responseTimestring | nullGoogle's response-time promise for the business, e.g. Typically replies in 30 min.
profileUrlstring | nullAbsolute link to the provider's Local Services profile page on Google.
isPreviewAdbooleantrue when Google flags the card as a non-live preview ad rather than a currently running one.
searchQuerystringWhich of your input search terms produced this row.
locationstringWhich of your input locations produced this row.
countryCodestringThe ISO-3166-1 alpha-2 country actually used for this search (auto-detected from the location, or your override) — this drives both Google's gl parameter and the proxy country.
positionnumberZero-based rank of this provider in Google's result list for this search (0 is the top ad).
sourceUrlstringThe exact google.com/localservices/prolist URL the actor requested to produce this row.
scrapedAtstringISO timestamp of when the row was extracted.

Input

FieldTypeRequiredDescription
searchQueriesarray of stringsYesServices to search for. Plain, everyday wording ("plumbers", "electricians") tends to return more results than Google's formal taxonomy names.
locationsarray of stringsYesCities or areas to search in. Include the state, province or country ("Austin, TX", not "Austin") so the right place — and country — is picked.
maxLeadsintegerNo (default 1000)A cap on the total number of providers saved across the whole run, not a per-search target. Read How many results can I get? before raising this.
minRatinginteger, 0–5NoOnly save providers rated at or above this. Leave empty to keep everything. Setting this excludes brand-new providers that have no rating yet.
minReviewsintegerNoOnly save providers with at least this many reviews.
proxyConfigurationobjectRequired for real resultsApify Proxy configuration. The actor automatically forces the proxy country to match each location's country. Residential proxies are strongly recommended.
countryCodestring (ISO-3166-1 alpha-2)NoOverrides the country the actor would otherwise detect from a location, e.g. US. Useful when a location name is ambiguous.
languageCodestringNo (default en)Two-letter language code for Google's interface and result text.

Example input:

{
"searchQueries": ["plumbers", "electricians"],
"locations": ["Austin, TX", "Toronto, ON"],
"maxLeads": 500,
"minRating": 4,
"minReviews": 5,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
},
"languageCode": "en"
}

This example runs 4 searches (2 services × 2 locations), each capped at Google's own 20-provider limit, and keeps only providers rated 4+ stars with at least 5 reviews.

Output example

A single row from the dataset, for a "plumbers near Toronto, ON" search:

{
"customerId": "5423178690",
"name": "Maple Leaf Plumbing & Drain",
"phone": "+14165550142",
"phoneDisplay": null,
"phoneRegionCode": "CA",
"businessId": "9082217634",
"providerId": "4471183920",
"rating": 4.9,
"reviewsCount": 214,
"providerType": "Plumber",
"yearsInBusinessText": "18+ years in business",
"yearsInBusiness": 18,
"serviceAreaText": "Serves Toronto",
"serviceArea": "Toronto",
"hours": "Open 24 hours",
"isOpenNow": true,
"badges": ["Google Guaranteed", "Background checked"],
"highlights": ["Family owned", "Emergency service"],
"responseTime": "Typically replies in 30 min",
"profileUrl": "https://www.google.com/localservices/prolist/provider?hl=en&gl=ca",
"isPreviewAd": false,
"searchQuery": "plumbers",
"location": "Toronto, ON",
"countryCode": "CA",
"position": 0,
"sourceUrl": "https://www.google.com/localservices/prolist?q=plumbers+near+Toronto%2C+ON&hl=en&gl=ca&src=1",
"scrapedAt": "2026-08-25T14:32:07.918Z"
}

("Maple Leaf Plumbing & Drain" is an illustrative business, not a real advertiser.)

How many results can I get?

Google caps every Local Services Ads search at a maximum of 20 providers per service, per location. This is a hard limit on Google's side — no offset, page or pagination parameter changes it, and scrolling the results pane doesn't load more. It's a fact about how Google serves LSA, not a limitation of this actor.

That means maxLeads is a ceiling, never a target: setting it to 5,000 will not make a single "plumbers near Austin, TX" search return more than 20 rows. If you need more than 20 leads, the only way to get there is to run more searches — add more service terms (plumbers, drain cleaning, water heater repair) and more locations (individual neighborhoods or nearby suburbs instead of one whole metro). Each service × location pair is its own search with its own 20-provider ceiling, so 10 services across 10 cities can return up to 2,000 rows in one run, provided maxLeads is raised above its default of 1,000 to allow it.

Why am I getting zero results?

Zero results almost always comes down to one of these, roughly in order of likelihood:

  1. Proxy/location country mismatch. Google only shows Local Services Ads to visitors it believes are physically in the same country as the requested service area. If your proxy exits in Canada while you search "Plumbing near Austin, TX", Google silently returns an empty "try a different area" page — not an error. The actor auto-matches the proxy country to each location (see step 3 of How do I scrape Google Local Services Ads?), so make sure your proxy configuration actually has access to the countries you're targeting (residential proxies with broad country coverage work best), and avoid overriding countryCode unless you're sure of the ISO code.
  2. There genuinely are no active LSA advertisers for that service in that area. Local Services Ads coverage varies a lot by city and category — a large metro will have 20 roofers advertising; a small town may have none. This is a real, expected zero, not a bug.
  3. The country isn't supported by Local Services Ads at all. Google runs LSA in a limited set of countries and is still expanding it. Check the official Google Local Services Ads page for current availability before assuming your setup is broken.
  4. Filters are removing everything. If you set minRating or minReviews, brand-new providers with no reviews yet are excluded entirely, which can take a run from 20 raw results down to very few (or zero) saved rows. Try the run with the filters cleared to confirm providers exist before re-adding them.

About the phone numbers

Google's own Local Services Ads page hides the phone number behind a "Get phone number" button — but the server-rendered HTML underneath ships the number anyway, in a data-phone-number attribute, on every provider card. The actor reads it directly, with no clicking and no browser involved, which is why phone is populated on effectively every row.

These are Google call-tracking numbers, not the business's direct line. Calls to them are forwarded to the actual business, and this is the number the advertiser pays Google to receive calls on — which makes it the correct number to use for outreach or lead delivery. phone is always in E.164 format (e.g. +14165550142). phoneDisplay only carries a value on the rare card where Google also renders visible display text for the number — in the normal case, where the UI hides it behind the "Get phone number" button, phoneDisplay is null and phone is the field to use. phoneRegionCode gives the two-letter region Google associates with the number.

FAQ

Do I need a proxy for this to work?

Yes. Local Services Ads is geo-gated by the requesting IP's country, so a proxy in the wrong country returns an empty result even for a real, active market. The proxyConfiguration input is required for real results, and residential proxies are recommended. See Why am I getting zero results?

Are the phone numbers real?

Yes — they ring through to the actual business — but they are Google call-tracking numbers, not the advertiser's private line. That's the number the advertiser pays Google to receive calls on, which makes it the right number for outreach. See About the phone numbers for format details.

Why do simple search terms like "plumbers" work better than Google's official category names?

Google's Local Services Ads search matches on plain, everyday wording. Colloquial terms such as roofers, electricians and plumbers return full result sets, while some formal taxonomy names return nothing. Type services the way a customer would search for them.

Can the same business appear twice, or two different businesses share a name?

Yes to both — business name is not a unique identifier on Google's side. Two distinct advertisers can list under an identical display name. Always dedupe or key your data on customerId, not name.

Is this a browser-based (Playwright/Selenium) scraper?

No. Google's Local Services results page is fully server-rendered, so the actor fetches it over plain HTTP and parses the HTML — no browser is launched. This makes runs fast and avoids browser-fingerprinting issues entirely.

Can I get more than 20 results for one service in one city?

No — that's Google's own per-search limit, not a setting in this actor. See How many results can I get? for how to scale up using more services and locations instead.

Will minRating or minReviews reduce my result count even when providers exist?

Yes. Both filters are applied after Google returns results, and minRating in particular drops every provider that has no rating yet (which includes brand-new advertisers). If a search that should have 20 providers returns far fewer, try the same run with these filters cleared to see the unfiltered count.


This is an independent tool built on publicly accessible Google Local Services Ads result pages. It is not affiliated with, endorsed by, or sponsored by Google LLC. "Google Local Services Ads" and "Google Guaranteed" are trademarks of Google LLC.