Como Scrapear Avaliações do Google Usando Python — Guia Completo de 2025
Avaliações do Google são uma mina de ouro de feedback dos clientes, mas coletar milhares delas manualmente? Isso é ineficiente e impraticável.
Com Python, você pode automatizar todo o processo de extração e reunir milhares de avaliações em poucas horas. Este guia o orienta em tudo — desde a configuração básica até scrapers prontos para produção que lidam com as defesas anti-scraping do Google.
Ao final, você entenderá como construir scrapers de avaliações confiáveis, evitar detecções e extrair insights acionáveis dos clientes em grande escala.
O que é Scraping de Avaliações do Google?
Scraping de avaliações do Google é a extração automatizada de dados de feedback dos clientes a partir do Google Maps e perfis do Google Business usando scripts em Python.
Quando você scrapeia avaliações do Google, você captura:
- Avaliações em estrelas (1–5 estrelas)
- Texto da avaliação (comentários completos dos clientes)
- Nomes e perfis dos avaliadores
- Datas e horários das avaliações
- Respostas das empresas (se o proprietário respondeu)
- Contagem de votos úteis
Diferente da API oficial do Google — que é cara e possui limites severos — o scraping lhe dá acesso a todas as avaliações disponíveis sem cotas ou restrições.
Por que Scrapear em vez de Usar a API do Google?
A API oficial do Google Places para avaliações tem limitações sérias:
| Recurso | API Oficial | Web Scraping |
|---|---|---|
| Avaliações por solicitação | ~10 (apenas recentes) | Todas disponíveis |
| Custo | $7 por 1.000 solicitações | Gratuito a baixo custo |
| Limites de taxa | 100 solicitações/segundo no máximo | Configurável |
| Avaliações de concorrentes | ❌ Não | ✅ Sim |
| Complexidade de configuração | Moderada (autenticação) | Maior (técnica) |
Para análise competitiva, pesquisa de mercado ou coleta de dados em grande escala, o scraping é a escolha prática.
Por que Python é a Melhor Linguagem para Esta Tarefa
Python domina o web scraping por três razões principais:
1. Ecossistema de Scraping Rico
Python possui bibliotecas específicas para web scraping:
- Playwright — Automação de navegador moderna e rápida
- Selenium — Testado em batalha, máxima compatibilidade
- BeautifulSoup — Análise leve de HTML
- Scrapy — Framework de scraping de nível empresarial
- Pandas — Manipulação e exportação de dados
Você pode passar de HTML bruto para CSV limpo em um único script.
2. Execução de JavaScript
Avaliações do Google carregam dinamicamente através de JavaScript, não no HTML inicial. As ferramentas de automação de navegador do Python (Playwright, Selenium) executam JavaScript como um navegador real, permitindo que você:
- Acione o scroll infinito
- Clique em botões "Mostrar mais"
- Espere o conteúdo aparecer
- Interaja com elementos da página
3. Recursos Anti-Detecção Integrados
Bibliotecas modernas do Python vêm com capacidades de stealth prontas para uso:
# Ocultar indicadores de automação
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
Essas flags impedem que o Google detecte seu script como um bot.
4. Pipeline de Processamento de Dados Sem Costura
Com Python, você scrapeia → limpa → analisa → exporta tudo em um único script. Nenhuma troca de ferramentas é necessária.
O Desafio: Por que o Google Torna o Scraping Difícil
O Google emprega múltiplas camadas anti-scraping. Compreender isso ajuda você a construir scrapers resilientes.
1. Carregamento de Conteúdo Dinâmico
Avaliações do Google não carregam todas de uma vez. Em vez disso:
- O carregamento inicial da página mostra 10–20 avaliações
- Avaliações adicionais carregam via AJAX conforme você rola
- Cada lote requer solicitações de rede separadas
- O mecanismo muda frequentemente
Solução: Use automação de navegador (Playwright/Selenium) que executa JavaScript e simula o scroll.
2. Detecção de Bots Sofisticada
O Google analisa:
- Impressão digital do navegador — Resolução de tela, fontes instaladas, fuso horário
- Padrões comportamentais — Movimentos do mouse, velocidade de rolagem, tempo de clique
- Frequência de solicitações — Detectando padrões de solicitações não humanas
- Reputação do IP — Marcando endereços suspeitos
Solução: Rotacione proxies, adicione atrasos aleatórios, use agentes de usuário realistas.
3. Limite de Taxas e CAPTCHAs
Se você pressionar o Google com muita força, enfrentará:
- Bloqueios temporários de IP (24–48 horas)
- Desafios CAPTCHA
- Negação total de acesso
- Throttling progressivo
Solução: Implemente throttling de solicitações (atrasos de 1–3 segundos entre ações).
4. Estrutura HTML em Evolução Constante
O Google atualiza regularmente a estrutura de suas páginas, quebrando seletores CSS da noite para o dia.
Solução: Use múltiplos seletores de fallback e consultas baseadas em atributos em vez de nomes de classes frágeis.
Método 1: Playwright — A Abordagem Moderna
Playwright é a escolha recomendada para 2025. É mais rápido que o Selenium, possui melhores recursos anti-detecção e lida facilmente com sites modernos pesados em JavaScript.
Configurando o Playwright
Primeiro, crie um ambiente virtual e instale as dependências:
# Criar ambiente virtual
python -m venv google_scraper
source google_scraper/bin/activate # No Windows: google_scraper\Scripts\activate
# Instalar pacotes necessários
pip install playwright pandas beautifulsoup4 lxml emoji
# Instalar navegador
playwright install chromium
Código Completo do Scraper Playwright
Aqui está um scraper pronto para produção que lida com as complexidades das avaliações do Google:
from playwright.sync_api import sync_playwright
import pandas as pd
import re
import emoji
import logging
import time
import random
from datetime import datetime
# Configurar logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
class GoogleReviewsScraper:
def __init__(self, headless=True):
self.headless = headless
self.reviews_data = []
def clean_text(self, text):
"""Remove emojis e normaliza o texto"""
if not text:
return ""
text = emoji.replace_emoji(text, replace='')
text = re.sub(r'\s+', ' ', text).strip()
return text
def random_delay(self, min_delay=1, max_delay=3):
"""Adiciona atrasos aleatórios para imitar o comportamento humano"""
delay = random.uniform(min_delay, max_delay)
time.sleep(delay)
def initialize_browser(self):
"""Inicializa o Playwright com configurações stealth"""
playwright = sync_playwright().start()
browser = playwright.chromium.launch(
headless=self.headless,
args=[
'--disable-blink-features=AutomationControlled',
'--disable-extensions',
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu'
]
)
context = browser.new_context(
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
viewport={'width': 1366, 'height': 768}
)
page = context.new_page()
# Ocultar propriedade do webdriver
page.add_init_script("""
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined,
});
""")
return playwright, browser, page
def search_business(self, page, business_name):
"""Busca por uma empresa no Google Maps"""
try:
page.goto("https://www.google.com/maps", wait_until="networkidle")
self.random_delay(2, 4)
# Encontrar caixa de pesquisa e inserir nome da empresa
search_box = page.locator("input[id='searchboxinput']")
search_box.fill(business_name)
search_box.press("Enter")
# Aguardar resultados carregarem
page.wait_for_timeout(5000)
logger.info(f"Buscou por: {business_name}")
return True
except Exception as e:
logger.error(f"Erro ao buscar empresa: {e}")
return False
def navigate_to_reviews(self, page):
"""Navega até a seção de avaliações"""
try:
# Procurar aba de avaliações
reviews_tab = page.get_by_role("tab", name=re.compile("Avaliações|avaliações", re.IGNORECASE))
if reviews_tab.is_visible():
reviews_tab.click()
page.wait_for_timeout(3000)
logger.info("Navegado para a seção de avaliações")
return True
else:
logger.warning("Aba de avaliações não encontrada")
return False
except Exception as e:
logger.error(f"Erro ao navegar para avaliações: {e}")
return False
def scroll_and_load_reviews(self, page, max_reviews=100):
"""Rola para carregar mais avaliações dinamicamente"""
loaded_reviews = 0
scroll_attempts = 0
max_scroll_attempts = 20
while loaded_reviews < max_reviews and scroll_attempts < max_scroll_attempts:
try:
# Rolar até o fundo
page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
self.random_delay(2, 4)
# Contar avaliações atuais
current_reviews = page.locator('[data-review-id]').count()
if current_reviews > loaded_reviews:
loaded_reviews = current_reviews
logger.info(f"Carregado {loaded_reviews} avaliações...")
scroll_attempts = 0 # Reiniciar contador
else:
scroll_attempts += 1
# Tentar clicar no botão "Mais avaliações" se disponível
try:
more_button = page.locator("button:has-text('Mais'), button:has-text('mais')")
if more_button.is_visible():
more_button.click()
self.random_delay(2, 3)
except:
pass
except Exception as e:
logger.error(f"Erro durante a rolagem: {e}")
break
logger.info(f"Carregamento finalizado. Total de avaliações: {loaded_reviews}")
return loaded_reviews
def extract_review_data(self, page):
"""Extrai dados individuais de avaliações da página carregada"""
reviews = []
try:
review_elements = page.locator('[data-review-id]').all()
for element in review_elements:
try:
review_data = {}
# Extrair nome do avaliador
try:
name_element = element.locator('div[class*="name"] span').first
review_data['reviewer_name'] = name_element.inner_text() if name_element.is_visible() else "Anônimo"
except:
review_data['reviewer_name'] = "Anônimo"
# Extrair avaliação
try:
rating_element = element.locator('[role="img"][aria-label*="star"]').first
if rating_element.is_visible():
rating_text = rating_element.get_attribute('aria-label')
rating_match = re.search(r'(\d+)', rating_text)
review_data['rating'] = int(rating_match.group(1)) if rating_match else None
else:
review_data['rating'] = None
except:
review_data['rating'] = None
# Extrair texto da avaliação
try:
text_elements = element.locator('span[class*="review-text"], div[class*="review-text"]').all()
review_text = ""
for text_elem in text_elements:
if text_elem.is_visible():
review_text += text_elem.inner_text() + " "
review_data['review_text'] = self.clean_text(review_text.strip())
except:
review_data['review_text'] = ""
# Extrair data
try:
date_element = element.locator('span[class*="date"], div[class*="date"]').first
review_data['review_date'] = date_element.inner_text() if date_element.is_visible() else "Desconhecido"
except:
review_data['review_date'] = "Desconhecido"
# Extrair contagem de úteis
try:
helpful_element = element.locator('[aria-label*="útil"], [aria-label*="Útil"]').first
if helpful_element.is_visible():
helpful_text = helpful_element.get_attribute('aria-label')
helpful_match = re.search(r'(\d+)', helpful_text)
review_data['helpful_count'] = int(helpful_match.group(1)) if helpful_match else 0
else:
review_data['helpful_count'] = 0
except:
review_data['helpful_count'] = 0
# Apenas adicionar avaliações com conteúdo de texto real
if review_data['review_text']:
reviews.append(review_data)
except Exception as e:
logger.warning(f"Erro ao extrair avaliação individual: {e}")
continue
logger.info(f"Extraído com sucesso {len(reviews)} avaliações")
return reviews
except Exception as e:
logger.error(f"Erro ao extrair avaliações: {e}")
return []
def scrape_reviews(self, business_name, max_reviews=100):
"""Método principal de scraping"""
playwright, browser, page = self.initialize_browser()
try:
# Buscar empresa
if not self.search_business(page, business_name):
return []
# Navegar até aba de avaliações
if not self.navigate_to_reviews(page):
return []
# Carregar avaliações rolando
self.scroll_and_load_reviews(page, max_reviews)
# Extrair dados das avaliações
reviews = self.extract_review_data(page)
self.reviews_data = reviews
return reviews
except Exception as e:
logger.error(f"Scraping falhou: {e}")
return []
finally:
browser.close()
playwright.stop()
def save_to_csv(self, filename="google_reviews.csv"):
"""Salva avaliações em arquivo CSV"""
if self.reviews_data:
df = pd.DataFrame(self.reviews_data)
df['extraction_date'] = datetime.now().isoformat()
df.to_csv(filename, index=False, encoding='utf-8')
logger.info(f"Avaliações salvas em {filename}")
print(f"✅ Exportado {len(self.reviews_data)} avaliações para {filename}")
else:
logger.warning("Nenhuma avaliação para salvar")
# Exemplo de uso
if __name__ == "__main__":
scraper = GoogleReviewsScraper(headless=False) # Defina como True para produção
business_name = "Starbucks Times Square New York"
reviews = scraper.scrape_reviews(business_name, max_reviews=50)
if reviews:
scraper.save_to_csv(f"reviews_{business_name.replace(' ', '_')}.csv")
print(f"✅ Avaliações {len(reviews)} extraídas com sucesso!")
else:
print("❌ Nenhuma avaliação foi extraída.")
Como Este Scraper Funciona
1. Configuração Stealth
O scraper oculta indicadores de automação que o Google usa para detectar bots:
options.add_argument("--disable-blink-features=AutomationControlled")
page.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
2. Atrasos Aleatórios
Em vez de disparar solicitações instantaneamente, o scraper espera de 1 a 3 segundos entre as ações para imitar a navegação humana.
3. Rolagem Dinâmica
Ele rola até o fundo da seção de avaliações repetidamente, acionando o mecanismo de scroll infinito do Google para carregar mais avaliações.
4. Tratamento Robusto de Erros
Se um seletor falhar (porque o Google mudou o HTML), o scraper tenta seletores de fallback em vez de travar.
5. Limpeza de Dados
Avaliações são limpas para remover emojis, normalizar espaços em branco e garantir dados de qualidade.
Método 2: Selenium — A Alternativa Testada em Batalha
Enquanto o Playwright é mais rápido, o Selenium continua sendo o padrão ouro para compatibilidade e possui uma comunidade enorme. Use o Selenium se precisar de suporte máximo ao navegador ou se já tiver infraestrutura existente do Selenium.
Instalação do Selenium
pip install selenium webdriver-manager pandas beautifulsoup4
# Baixar ChromeDriver (gerenciado automaticamente pelo webdriver-manager)
Implementação Completa do Selenium
```python from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.action_chains import ActionChains from selenium.common.exceptions import TimeoutException, NoSuchElementException import pandas as pd import time import random import re import logging from datetime import datetime
logging.basicConfig(level=logging.INFO) logger = logging.getLogger(name)
class SeleniumGoogleReviewsScraper: def init(self, headless=True): self.headless = headless self.driver = None self.wait = None self.reviews_data = []
def setup_driver(self):
"""Configura e inicializa o driver do Chrome"""
options = Options()
if self.headless:
options.add_argument("--headless")
# Medidas anti-detecção
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument("--disable-extensions")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--disable-gpu")
options.add_argument("--window-size=1366,768")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
self.driver = webdriver.Chrome(options=options)
# Ocultar propriedade do webdriver
self.driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined,});")
self.wait = WebDriverWait(self.driver, 20)
logger.info("Driver do Chrome inicializado")
def random_delay(self, min_seconds=1, max_seconds=3):
"""Adiciona atrasos aleatórios entre ações"""
delay = random.uniform(min_seconds, max_seconds)
time.sleep(delay)
def search_google_maps(self, business_name):
"""Busca por empresa no Google Maps"""
try:
self.
Pronto para começar?
Aceda a todas as empresas do Google Maps, enriquecidas com emails e dados legais.
Experimente o IBLead gratuitamenteArtigos relacionados
10 Dicas Comprovadas para Fazer Clientes Deixarem Mais Avaliações no Google Maps
Aprenda 10 estratégias práticas para aumentar as avaliações no Google Maps. Táticas que realmente funcionam.
7 Erros de Cold Email para Evitar: Exemplos e Modelos
Evite esses 7 erros de cold email que matam as taxas de resposta. Exemplos reais, modelos AIDA e soluções comprovadas para melhor prospecção.
Dados do Google Maps para ABM: O Guia Estratégico Completo
Descubra como os dados do Google Maps para marketing baseado em contas geram 208% mais receita. Crie listas de alvos precisas com 50M+ empresas.