How to Scrape Google Reviews: A Step-by-Step Guide
In this guide, I’ll show you how to scrape Google Reviews using Python to easily gather and analyze data from Google Maps listings. Whether you’re looking to track customer sentiment, spot trends, or simply collect reviews at scale, this simple and scalable method will help you get the job done. So, you’ll have a clear process to start scraping and extracting useful data from Google Reviews to drive your business forward.
Short on time? Here are the top 3 providers to scrape Google Reviews without the hassle:
- Bright Data: Industry leader with dedicated Google Maps APIs, rotating proxies, and a scraping browser that handles anti-bot measures automatically. Best for scale and reliability.
- Oxylabs: Powerful scraping infrastructure with real-time SERP APIs and extensive proxy networks. Great for enterprise-level data collection.
- ScraperAPI: Simple API that handles proxies, browsers, and CAPTCHAs for you. Budget-friendly option for smaller projects.
👇 Want to build your own scraper? Keep reading for the full Python tutorial.
What is Web Scraping?
Web scraping is the process of extracting data from websites. It involves retrieving a webpage’s content and pulling out the information you need. When it comes to Google Reviews, web scraping helps businesses collect valuable customer feedback about their products or services.
This data can be used to analyze customer opinions, identify areas of improvement, or report on business performance. By scraping Google Reviews, businesses can gain insights into customer satisfaction and use that information to improve the overall customer experience and make informed decisions for growth.
Why Scrape Google Reviews?
Google Reviews are a goldmine of information. They provide businesses with direct feedback from their customers, which can be helpful in several ways:
- Customer Satisfaction: Learn what customers like and dislike about your business.
- Competitive Analysis: Compare reviews across competitors to identify areas of improvement.
- SEO Benefits: Positive reviews can improve your website’s search engine rankings.
- Brand Monitoring: Stay updated on how your brand is perceived by the public.
Scraping Google Reviews helps businesses access these insights at scale, saving time and effort compared with manually reading individual reviews.
Tools Required for Scraping Google Reviews
To scrape Google Reviews, you’ll need the following tools:
- Programming Language: Python is one of the most popular languages for web scraping because of its simplicity and powerful libraries.
- Libraries: For this tutorial, we’ll use libraries such as
requests,BeautifulSoup, andSeleniumfor scraping. BeautifulSoup helps parse the HTML content of a webpage, while Selenium can handle JavaScript-heavy websites like Google Maps. - Proxy Services: Google has strict measures in place to block scrapers. To avoid being blocked, you’ll need to use proxy services, such as Bright Data or Oxylabs, to rotate IP addresses.
- Browser Automation Tools: Some pages require interaction (like clicking buttons or scrolling). Selenium can automate these actions.
How to Scrape Google Reviews from a Single Listing
The first step is to scrape reviews from a single Google Maps listing page. Google Maps provides a wealth of data, including customer reviews, star ratings, and reviewer details.
Step 1: Set Up Your Python Environment
To get started, ensure Python is installed on your system. You can install the necessary libraries by running the following commands:
pip install requests
pip install beautifulsoup4
pip install selenium
Step 2: Identify the Google Reviews Page
The URL for a Google Maps business listing typically looks like this:
https://www.google.com/maps/place/{business_name}/@latitude,longitude
Visit the Google Maps page for your business and copy the URL.
Step 3: Use Selenium to Open the Google Maps Listing
Google Maps requires JavaScript rendering to display reviews, so we’ll use Selenium to simulate browser interactions. Below is a simple Selenium script that opens a Google Maps listing and clicks the reviews tab.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time
# Set up the Selenium WebDriver (Selenium 4 auto-manages ChromeDriver)
chrome_options = Options()
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.google.com/maps/place/The Manhattan at Times Square Hotel")
# Wait for the page to load
time.sleep(5)
# Click the reviews tab using a flexible selector
reviews_tab = driver.find_element(By.XPATH, "//button[contains(@aria-label, 'Reviews')]")
reviews_tab.click()
# Wait for reviews to load
time.sleep(3)
Step 4: Scroll to Load All Reviews
Google Maps uses infinite scrolling within a specific panel to load reviews — not the window body. To scrape all reviews, you need to simulate scrolling within the reviews container.
# Find the scrollable reviews panel
scrollable_div = driver.find_element(By.CSS_SELECTOR, ".m6QErb.DxyBCb.kA9KIf.dS8AEf.XiKgde")
# Scroll within the panel to load all reviews
for _ in range(10): # Adjust the range for more scrolling
driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", scrollable_div)
time.sleep(2)
Step 5: Extract Review Data
Once the reviews are loaded, you can use BeautifulSoup to parse the page and extract the review details. Here’s an example of how to extract the review text, reviewer name, rating, and date:
from bs4 import BeautifulSoup
# Get page source after scrolling
html = driver.page_source
# Parse the page using BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# Find all review containers
reviews = soup.find_all("div", class_="jftiEf")
# Extract relevant data from each review
review_data = []
for review in reviews:
# Reviewer name
name_elem = review.find("div", class_="d4r55")
reviewer_name = name_elem.text.strip() if name_elem else "No name"
# Review text
text_elem = review.find("span", class_="wiI7pd")
review_text = text_elem.text.strip() if text_elem else "No review text"
# Rating (count filled stars)
rating_container = review.find("span", class_="hCCjke")
if rating_container:
filled_stars = rating_container.find_all("span", class_="NhBTye")
rating = len(filled_stars)
else:
rating = 0
# Review date
date_elem = review.find("span", class_="rsqaWe")
review_date = date_elem.text.strip() if date_elem else "No date"
review_data.append({
"reviewer": reviewer_name,
"review_text": review_text,
"rating": rating,
"review_date": review_date
})
print(review_data)
Step 6: Handle “More” Button for Long Reviews
Some reviews may be truncated with a “More” button that hides part of the review. You can automate clicking this button using Selenium:
# Click "More" to reveal the full review text
more_buttons = driver.find_elements(By.CSS_SELECTOR, ".w8nwRe.kyuRq")
for button in more_buttons:
try:
button.click()
time.sleep(0.5)
except:
pass # Button may not be clickable or visible
Step 7: Save the Data
Once you’ve extracted the data, you can save it in a CSV, JSON, or database. For this example, we’ll save the data to a JSON file.
import json
with open("reviews.json", "w", encoding="utf-8") as file:
json.dump(review_data, file, indent=4, ensure_ascii=False)
Scaling the Scraping Process to Multiple Listings
Now that you’ve learned how to scrape a single listing, it’s time to scale the process to multiple business listings.
Step 1: Extract Multiple URLs
Google Maps search pages provide links to individual business listings. To scrape reviews from multiple listings, first extract the URLs of the businesses from a search page.
def extract_listing_urls(search_url):
driver.get(search_url)
time.sleep(5)
# Find the scrollable search results panel
try:
scrollable_div = driver.find_element(By.CSS_SELECTOR, ".m6QErb.DxyBCb.kA9KIf.dS8AEf.XiKgde.ecceSd")
for _ in range(5):
driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", scrollable_div)
time.sleep(2)
except Exception as e:
print(f"Scrolling error: {e}")
# Extract the URLs of the listings
listing_elements = driver.find_elements(By.CSS_SELECTOR, "a.hfpxzc")
urls = [element.get_attribute("href") for element in listing_elements]
return urls
listing_urls = extract_listing_urls("https://www.google.com/maps/search/hotels in new york")
print(listing_urls)
Step 2: Scrape Reviews from Each Listing
Once you have the listing URLs, you can iterate over each URL and scrape reviews using the same method you used for the single listing.
all_reviews = []
for url in listing_urls:
reviews = scrape_reviews(url)
all_reviews.append({
"url": url,
"reviews": reviews
})
# Save all reviews to a JSON file
with open("all_reviews.json", "w", encoding="utf-8") as file:
json.dump(all_reviews, file, indent=4, ensure_ascii=False)
Handling CAPTCHA and Anti-Scraping Measures
Google uses CAPTCHA and other anti-bot measures to prevent scraping. To bypass these restrictions, you can use services like Bright Data or Oxylabs. These services provide rotating proxies and browser automation solutions, allowing you to scrape data without being blocked.
Here’s how to use a proxy service to bypass CAPTCHA:
- Sign Up: Create an account on Bright Data or Oxylabs and obtain your API key or proxy credentials.
- Configure Proxy Settings: Use rotating proxies to change IP addresses and avoid being blocked.
- Integrate with Selenium: Set up the proxy in Selenium to route requests through the service.
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
# Example proxy configuration
proxy = "http://username:password@proxy-server:port"
chrome_options.add_argument(f'--proxy-server={proxy}')
driver = webdriver.Chrome(options=chrome_options)
Complete Working Script
Here’s the full script combining all the steps above:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import json
import time
def setup_driver():
"""Set up and return the Selenium WebDriver"""
chrome_options = Options()
# chrome_options.add_argument("--headless") # Uncomment for headless mode
driver = webdriver.Chrome(options=chrome_options)
return driver
def scrape_reviews(driver, url):
"""Scrape reviews from a single Google Maps listing"""
driver.get(url)
time.sleep(5)
# Click the Reviews tab
try:
reviews_tab = driver.find_element(By.XPATH, "//button[contains(@aria-label, 'Reviews')]")
reviews_tab.click()
time.sleep(3)
except Exception as e:
print(f"Could not click Reviews tab: {e}")
return []
# Scroll within the reviews panel to load more reviews
try:
scrollable_div = driver.find_element(By.CSS_SELECTOR, ".m6QErb.DxyBCb.kA9KIf.dS8AEf.XiKgde")
for _ in range(10):
driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", scrollable_div)
time.sleep(2)
except Exception as e:
print(f"Scrolling error: {e}")
# Click all "More" buttons to expand truncated reviews
more_buttons = driver.find_elements(By.CSS_SELECTOR, ".w8nwRe.kyuRq")
for button in more_buttons:
try:
button.click()
time.sleep(0.5)
except:
pass
# Parse page with BeautifulSoup
html = driver.page_source
soup = BeautifulSoup(html, "html.parser")
# Find all review containers
reviews = soup.find_all("div", class_="jftiEf")
review_data = []
for review in reviews:
# Reviewer name
name_elem = review.find("div", class_="d4r55")
reviewer_name = name_elem.text.strip() if name_elem else "No name"
# Review text
text_elem = review.find("span", class_="wiI7pd")
review_text = text_elem.text.strip() if text_elem else "No review text"
# Rating (count filled stars)
rating_container = review.find("span", class_="hCCjke")
if rating_container:
filled_stars = rating_container.find_all("span", class_="NhBTye")
rating = len(filled_stars)
else:
rating = 0
# Review date
date_elem = review.find("span", class_="rsqaWe")
review_date = date_elem.text.strip() if date_elem else "No date"
review_data.append({
"reviewer": reviewer_name,
"review_text": review_text,
"rating": rating,
"review_date": review_date
})
return review_data
def extract_listing_urls(driver, search_url):
"""Extract listing URLs from a Google Maps search page"""
driver.get(search_url)
time.sleep(5)
# Scroll to load more listings
try:
scrollable_div = driver.find_element(By.CSS_SELECTOR, ".m6QErb.DxyBCb.kA9KIf.dS8AEf.XiKgde.ecceSd")
for _ in range(5):
driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", scrollable_div)
time.sleep(2)
except Exception as e:
print(f"Scrolling error: {e}")
# Extract listing URLs
listing_elements = driver.find_elements(By.CSS_SELECTOR, "a.hfpxzc")
urls = [element.get_attribute("href") for element in listing_elements]
return urls
# Main execution
if __name__ == "__main__":
driver = setup_driver()
try:
# Single listing example
single_url = "https://www.google.com/maps/place/The Manhattan at Times Square Hotel"
reviews = scrape_reviews(driver, single_url)
print(f"Scraped {len(reviews)} reviews from single listing")
# Save single listing reviews
with open("single_reviews.json", "w", encoding="utf-8") as file:
json.dump(reviews, file, indent=4, ensure_ascii=False)
# Multiple listings example
search_url = "https://www.google.com/maps/search/hotels in new york"
listing_urls = extract_listing_urls(driver, search_url)
print(f"Found {len(listing_urls)} listings")
all_reviews = []
for url in listing_urls[:5]: # Limit to first 5 for demo
reviews = scrape_reviews(driver, url)
all_reviews.append({
"url": url,
"reviews": reviews
})
print(f"Scraped {len(reviews)} reviews from {url[:50]}...")
# Save all reviews to JSON
with open("all_reviews.json", "w", encoding="utf-8") as file:
json.dump(all_reviews, file, indent=4, ensure_ascii=False)
print("All reviews saved to all_reviews.json")
finally:
driver.quit()
CSS Selector Reference
Here’s a quick reference table for the CSS selectors used in this tutorial:

⚠️ Important Note: Google Frequently Changes Selectors
Google regularly updates its CSS class names and page structure, often without warning. The selectors in this tutorial were verified as of January 2025, but they may break at any time.
If your scraper suddenly stops working, you’ll need to:
- Open Google Maps in your browser
- Right-click on the elements you want to scrape
- Select “Inspect” to open DevTools
- Find the new class names and update your code
For production use cases, consider using professional scraping services like Bright Data or Oxylabs. These platforms offer:
- Pre-built Google Maps APIs that handle selector changes automatically
- Rotating proxies to avoid IP blocks and CAPTCHAs
- Scraping browsers with built-in anti-detection measures
- Structured data output without needing to parse HTML yourself
- 99% success rates even on heavily protected sites
While building your own scraper is a great learning exercise, maintaining it long-term can become a significant time investment. Professional services abstract away these challenges and let you focus on using the data rather than fighting to collect it.
Final Words
Scraping Google Reviews is a valuable tool for businesses to gain insights into customer feedback at scale. By using Python and libraries like Selenium and BeautifulSoup, you can easily scrape reviews from Google Maps listings. Scaling this process to multiple listings can provide even more valuable data for your analysis.
While scraping data from Google comes with its challenges, including dynamic content loading, infinite scrolling, and anti-bot protections, the techniques covered in this guide will help you overcome them. For larger scale operations or production systems, consider using professional proxy and scraping services to ensure reliability and avoid blocks.
With this guide, you can now scrape Google Reviews and use the data to improve your business’s performance and customer satisfaction.

