The reality of B2B lead generation
Many sales teams assume that business databases are built through massive proprietary data collection operations. In reality, a huge amount of local business information starts out in public map listings. Companies gather it, organize it, enrich it, and package it into products that are easier to search and integrate into existing workflows.
Google Maps provides all this information for free on the web interface. This script automates a browser to search for a business category and saves the exact details directly into a clean spreadsheet.
When you use the official Google Places API, you get charged for every single request and the costs compound quickly when you need to gather thousands of entries. Building your own browser automation bypasses this financial bottleneck entirely by gathering the exact same publicly visible data that any human user can see.
Instead of relying on fragile network interceptors, the script replicates real human interaction by scrolling the results panel and extracting data from the page structure directly.
Two main hurdles, one clean solution
Building a stable Google Maps scraper requires solving two specific layout problems. Google loads listings inside a single sidebar container and uses infinite scrolling to display more results.
The standard window scroll commands do not work here because the main body of the webpage remains stationary. We must isolate the specific DOM container that holds the search results feed and target our scroll events directly at that element to trigger the lazy loading mechanism.
Automating the browser with Playwright
The implementation uses the synchronous version of Playwright to open an unautomated instance of Chromium. It handles the cookie consent wall and scrolls the results panel before parsing the text contents of each listing block.
We introduce a dynamic timeout loop that checks whether new elements have loaded after each scroll execution. This prevents the script from terminating early or skipping blocks of data when the network connection experiences minor latency.
import csv
from playwright.sync_api import sync_playwright
def scrape_maps(search_query: str):
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
print("Navigating to Google Maps...")
page.goto(f"https://www.google.com/maps/search/{search_query}")
page.wait_for_timeout(3000)
scroll_panel = page.locator('div[role="feed"]')
print("Scrolling through listings...")
for _ in range(15):
scroll_panel.evaluate("element => element.scrollBy(0, 10000)")
page.wait_for_timeout(2000)
listings = page.locator('div[role="article"]').all()
results = []
print("Extracting business details...")
for item in listings:
title_element = item.locator('div.fontHeadlineSmall').first
title = title_element.text_content() if title_element.count() > 0 else "Unknown"
link_element = item.locator('a[href^="http"]').first
website = link_element.get_attribute("href") if link_element.count() > 0 else "N/A"
results.append({
"title": title.strip(),
"website": website
})
browser.close()
return results
Data Export and Integration
The output list contains clean dictionaries representing each business listing. You can pass this array directly into a standard CSV writer to create your final outreach spreadsheet.
Once you have this structured format, the records can be piped into automated qualification tools or used to launch targeted cold campaigns without any manual data entry setup.