How to Scrape Google Maps in 2026: A Step-by-Step Guide with ProxyTee
Learn how to scrape Google Maps business listings, reviews, and coordinates in 2026 using Python, Selenium, and ProxyTee residential proxies.

Learn how to scrape Google Maps business listings, reviews, and coordinates in 2026 using Python, Selenium, and ProxyTee residential proxies.
Google Maps is a fantastic resource, allowing you to explore the world virtually and discover countless points of interest. For travelers, it’s an essential tool for planning journeys. But for data enthusiasts, Google Maps is a goldmine of constantly updated information, from restaurants and hotels to landmarks and service providers. In this post, we'll delve into the advantages of scraping Google Maps, provide a thorough walkthrough on how to do it using Python with ProxyTee residential proxies, and highlight our ready-made scraper for those who'd rather avoid coding.

Why Scrape Google Maps?
Google Maps offers a wealth of valuable data that's updated daily. It covers a vast range of categories, including eateries, supermarkets, accommodations, and many more. This information can be critical for businesses and analysts for several applications: market analysis, price monitoring, brand tracking, competitor research, and beyond. Additionally, it aids in customer engagement, location strategies, and service optimization. This level of detail can provide a competitive edge in numerous sectors.
Scraping Google Maps Using Python with ProxyTee
While the official Google Maps API is an option, it often comes with restrictions, query limitations, and costs, especially for large-scale data collection. So, we recommend a custom scraping approach. In this guide, we’ll utilize the Selenium web automation tool, enhanced by the Selenium Wire library for proxy support, Webdriver Manager for automatic browser driver management, and Beautiful Soup for HTML parsing. Our example will target Google Maps search results for falafel establishments in London.
Setting up the Development Environment
Ensure that you have Python installed and use pip (or pip3) to install these required libraries:
pip install selenium selenium-wire webdriver-manager beautifulsoup4
Then, import these libraries into your Python script:
from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import time
import csv
Integrating ProxyTee Residential Proxies
Proxies are vital for scraping, ensuring anonymity and avoiding blocks from target sites like Google Maps by routing requests through various IPs. Proxies also enable you to scale your efforts and access geo-restricted content. We'll use ProxyTee's rotating residential proxies in this tutorial, but you can use other types of proxies depending on your specific needs.
If you don’t have a ProxyTee account, create one on our website and select the plan that suits your requirements. Then, head to the Proxy setup to generate an endpoint by selecting the desired parameters, such as authentication method, location, session type, and protocol.
Here's how to integrate your proxy settings with Selenium Wire, replacing `username` and `password` with your actual credentials:
proxy_username = 'username'
proxy_password = 'password'
seleniumwire_options = {
'proxy': {
'http': f'http://{proxy_username}:{proxy_password}@gate.proxytee.com:10000',
'verify_ssl': False,
}
}
For location-specific data, such as falafel restaurants in London, you can use geo-targeted proxies. Change your proxy endpoint accordingly:
'http': f'http://{proxy_username}:{proxy_password}@city.proxytee.com:21250',
Finally, initiate the Selenium Wire driver with the given proxy configuration:
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, seleniumwire_options=seleniumwire_options)
Automating Browser Actions
Due to Google Maps' reliance on JavaScript, dynamic elements require a tool like Selenium to simulate user interactions for content to load correctly. First, instruct your browser to navigate to the target URL:
url = "https://www.google.com/maps/search/falafel+in+london/"
driver.get(url)
Next, bypass any cookie consent requests if necessary. We’ll implement this by locating and clicking the “Accept All” button:
try:
button = driver.find_element(By.XPATH, "//button[@class='VfPpkd-LgbsSe VfPpkd-LgbsSe-OWXEXe-k8QpJ VfPpkd-LgbsSe-OWXEXe-dgl2Hf nCP5yc AjY5Oe DuMIQc LQeN7 XWZjwc']")
button.click()
print("Clicked consent to cookies.")
except:
print("No consent required.")
Now, add a waiting period for the content to load completely, and capture a screenshot as reference:
driver.implicitly_wait(30) # Wait for max 30 seconds
screenshot_path = '/path/to/your/destination/screenshot.png'
driver.save_screenshot(screenshot_path)
print(f"Screenshot saved to {screenshot_path}")
To load all available places, use the following function to implement browser scrolling:
def scroll_panel_with_page_down(driver, panel_xpath, presses, pause_time):
"""Scrolls within a specific panel by simulating Page Down key presses.
:param driver: The Selenium WebDriver instance.
:param panel_xpath: The XPath to the panel element.
:param presses: The number of times to press the Page Down key.
:param pause_time: Time to pause between key presses, in seconds.
"""
panel_element = driver.find_element(By.XPATH, panel_xpath)
actions = ActionChains(driver)
actions.move_to_element(panel_element).click().perform()
for _ in range(presses):
actions = ActionChains(driver)
actions.send_keys(Keys.PAGE_DOWN).perform()
time.sleep(pause_time)
panel_xpath = "//*[@id='QA0Szd']/div/div/div[1]/div[2]/div"
scroll_panel_with_page_down(driver, panel_xpath, presses=5, pause_time=1)
After all this, the HTML content of the page can be retrieved for further analysis:
page_source = driver.page_source
Parsing and Storing Data
Now, it is time to use BeautifulSoup to parse and organize the collected data and then save to a CSV file. First, let's initialize BeautifulSoup with the HTML content:
soup = BeautifulSoup(page_source, "html.parser")
Then, we'll retrieve all titles, ratings, reviews, and services for each place using their respective CSS classes (note that class names on Google Maps might change, so please inspect them before using):
titles = soup.find_all(class_="hfpxzc")
ratings = soup.find_all(class_='MW4etd')
reviews = soup.find_all(class_='UY7F9')
services = soup.find_all(class_='Ahnjwc')
To get feedback on the quantity of information gathered:
elements_count = len(titles)
print(f"Number of places found: {elements_count}")
Finally, the following part saves data to a CSV file:
csv_file_path = '/path/to/your/destination/places.csv'
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerow(['Place', 'Rating', 'Reviews', 'Service options'])
for i, title in enumerate(titles):
title = title.get('aria-label')
rating = (ratings[i].text + "/5") if i < len(ratings) else 'N/A'
review_count = reviews[i].text if i < len(reviews) else 'N/A'
service = services[i].text if i < len(services) else 'N/A'
if title:
csv_writer.writerow([title, rating, review_count, service])
print(f"Data has been saved to '{csv_file_path}'")
To finish the script, close the browser window:
driver.quit()
Here’s the full Python script for your reference:
from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import time
import csv
# Selenium Wire configuration to use a proxy
proxy_username = 'username'
proxy_password = 'password'
seleniumwire_options = {
'proxy': {
'http': f'http://{proxy_username}:{proxy_password}@city.proxytee.com:21250',
'verify_ssl': False,
},
}
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, seleniumwire_options=seleniumwire_options)
# URL of the web page
url = "https://www.google.com/maps/search/falafel+in+london/"
# Open the web page
driver.get(url)
try:
button = driver.find_element(By.XPATH, "//button[@class='VfPpkd-LgbsSe VfPpkd-LgbsSe-OWXEXe-k8QpJ VfPpkd-LgbsSe-OWXEXe-dgl2Hf nCP5yc AjY5Oe DuMIQc LQeN7 XWZjwc']")
button.click()
print("Clicked consent to cookies.")
except:
print("No consent required.")
# Set an implicit wait time to wait for JavaScript to render
driver.implicitly_wait(30)
# Take a screenshot after the content you want is loaded
screenshot_path = '/path/to/your/destination/screenshot.png'
driver.save_screenshot(screenshot_path)
print(f"Screenshot saved to {screenshot_path}")
def scroll_panel_with_page_down(driver, panel_xpath, presses, pause_time):
"""Scrolls within a specific panel by simulating Page Down key presses.
:param driver: The Selenium WebDriver instance.
:param panel_xpath: The XPath to the panel element.
:param presses: The number of times to press the Page Down key.
:param pause_time: Time to pause between key presses, in seconds.
"""
panel_element = driver.find_element(By.XPATH, panel_xpath)
actions = ActionChains(driver)
actions.move_to_element(panel_element).click().perform()
for _ in range(presses):
actions = ActionChains(driver)
actions.send_keys(Keys.PAGE_DOWN).perform()
time.sleep(pause_time)
panel_xpath = "//*[@id='QA0Szd']/div/div/div[1]/div[2]/div"
scroll_panel_with_page_down(driver, panel_xpath, presses=5, pause_time=1)
# Get the page HTML source
page_source = driver.page_source
# Parse the HTML using BeautifulSoup
soup = BeautifulSoup(page_source, "html.parser")
# Find all elements using its class
titles = soup.find_all(class_="hfpxzc")
ratings = soup.find_all(class_='MW4etd')
reviews = soup.find_all(class_='UY7F9')
services = soup.find_all(class_='Ahnjwc')
# Print the number of places found
elements_count = len(titles)
print(f"Number of places found: {elements_count}")
# Specify the CSV file path
csv_file_path = '/path/to/your/destination/places.csv'
# Open a CSV file in write mode
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csv_file:
# Create a CSV writer object
csv_writer = csv.writer(csv_file)
# Write the header row (optional, adjust according to your data)
csv_writer.writerow(['Place', 'Rating', 'Reviews', 'Service options'])
# Write the extracted data
for i, title in enumerate(titles):
title = title.get('aria-label')
rating = (ratings[i].text + "/5") if i < len(ratings) else 'N/A'
review_count = reviews[i].text if i < len(reviews) else 'N/A'
service = services[i].text if i < len(services) else 'N/A'
# Write a row to the CSV file
if title:
csv_writer.writerow([title, rating, review_count, service])
print(f"Data has been saved to '{csv_file_path}'")
# Close the WebDriver
driver.quit()
This script helps you scrape information about falafel places in London and adapt this for other searches in other locations.
Ready-Made Google Maps Scraper from ProxyTee
Alternatively, ProxyTee offers the SERP Scraping API with a built-in scraper specifically for Google Maps. This eliminates the need for custom coding and lets you get the HTML data. Here’s how to start:
- Visit your ProxyTee dashboard.
- Go to Scraping APIs and select Pricing and then select SERP target group to choose the plan.
- Select the Scrapers tab and select Google Maps to get ready-made scraper.
- Enter your query and specify necessary parameters like location, language, domain, browser, and more.
- Click on Save & Scrape or Schedule your scraping job.
The output will be provided in HTML format, which you can then parse and use.
Conclusion
Congratulations! You have now learned how to scrape Google Maps by using Python with ProxyTee residential proxies. Just make sure to modify your script to adapt to any changes on Google Maps and equip yourself with proxies to ensure smooth and continuous data collection. Alternatively, our pre-built scraper is a quick and easy way to collect data without any code. Get started now with our unlimited residential proxies and start collecting valuable data.
To scale this workflow in production without bandwidth throttling, explore our Google SERP, Maps & Shopping Proxies, Selenium & SeleniumBase Integration, United Kingdom Residential Proxies, and ProxyTee vs. Oxylabs Benchmark.
Frequently Asked Questions
When scraping Google Maps local business listings, modern anti-bot firewalls (Cloudflare, Akamai, DataDome, PerimeterX) inspect ASN ownership, request velocity, and TLS fingerprints. Routing your traffic through ProxyTee's 30,000,000+ real household residential IPs across 100+ countries replaces flagged datacenter subnets with authentic consumer ISP connections.
Principal infrastructure engineer at ProxyTee specializing in rotating residential proxy networks, SOCKS5/HTTP tunneling, TLS fingerprint mitigation, and distributed data extraction pipelines.


