Como Fazer Scraping de Avalia\u00e7\u00f5es do Google Maps com Python em 2026 \u2014 Guia Completo

Um tutorial passo a passo e amig\u00e1vel para iniciantes sobre como fazer scraping de avalia\u00e7\u00f5es do Google Maps com Python usando Playwright e Selenium. Inclui c\u00f3digo funcional, dicas anti-detec\u00e7\u00e3o e uma alternativa no-code mais f\u00e1cil com o Livescraper.

Livescraper TeamApr 6, 2026
Como Fazer Scraping de Avalia\u00e7\u00f5es do Google Maps com Python em 2026 \u2014 Guia Completo

Se voc\u00ea j\u00e1 tentou copiar e colar avalia\u00e7\u00f5es do Google Maps na m\u00e3o, sabe bem a dor. Clicar num neg\u00f3cio, rolar pelas avalia\u00e7\u00f5es, copiar uma por uma... faz isso pra 50 neg\u00f3cios e l\u00e1 se vai a tarde inteira. J\u00e1 passei por isso.

\u00c9 por isso que fazer scraping de avalia\u00e7\u00f5es do Google Maps com Python faz tanto sentido. Voc\u00ea escreve o c\u00f3digo uma vez e ele faz todo o trabalho chato por voc\u00ea \u2014 puxando nomes dos avaliadores, notas em estrelas, o texto completo da avalia\u00e7\u00e3o, datas, tudo. Seja pra monitorar a reputa\u00e7\u00e3o da sua pr\u00f3pria marca, ficar de olho nos concorrentes ou montar um dataset pra algum projeto de pesquisa, automa\u00e7\u00e3o \u00e9 o caminho.

Neste guia, vou te mostrar duas formas diferentes de fazer isso: uma usando Playwright e outra usando Selenium. As duas funcionam. Tamb\u00e9m vou mostrar como driblar os sistemas anti-bot do Google (porque sim, eles v\u00e3o tentar te bloquear), e se voc\u00ea preferir pular todo o c\u00f3digo, vou te indicar uma ferramenta no-code que resolve tudo.

Voc\u00ea n\u00e3o precisa ser expert em Python pra acompanhar. Se consegue instalar uma biblioteca e rodar um script, t\u00e1 pronto.

O Que S\u00e3o Avalia\u00e7\u00f5es do Google Maps e Por Que Fazer Scraping Delas?

Voc\u00ea j\u00e1 sabe o que s\u00e3o avalia\u00e7\u00f5es do Google Maps \u2014 aquelas notas em estrelas e coment\u00e1rios que as pessoas deixam nos neg\u00f3cios. Toda pizzaria, consult\u00f3rio de dentista, hotel e encanador no Google Maps tem. O que talvez voc\u00ea n\u00e3o perceba \u00e9 quanta informa\u00e7\u00e3o \u00fatil t\u00e1 guardada nessas avalia\u00e7\u00f5es.

Que Dados Voc\u00ea Consegue Extrair?

Aqui est\u00e1 o que voc\u00ea pode puxar de cada avalia\u00e7\u00e3o:

  • Nome do avaliador \u2014 quem escreveu
  • Nota em estrelas \u2014 a pontua\u00e7\u00e3o de 1 a 5 estrelas
  • Texto da avalia\u00e7\u00e3o \u2014 o coment\u00e1rio que a pessoa deixou
  • Data da avalia\u00e7\u00e3o \u2014 quando foi publicada
  • Resposta do propriet\u00e1rio \u2014 se o neg\u00f3cio respondeu, voc\u00ea pega isso tamb\u00e9m
  • Link do perfil do avaliador \u2014 a URL do perfil Google da pessoa
  • Fotos da avalia\u00e7\u00e3o \u2014 qualquer imagem que a pessoa anexou

E O Que as Pessoas Realmente Fazem Com Esses Dados?

Bastante coisa, na verdade:

  • Monitoramento de marca \u2014 acompanhar o que as pessoas falam do seu neg\u00f3cio em diferentes localiza\u00e7\u00f5es
  • Pesquisa de concorrentes \u2014 descobrir onde os concorrentes est\u00e3o pecando (ou mandando bem) com base nas avalia\u00e7\u00f5es
  • An\u00e1lise de sentimento \u2014 passar as avalia\u00e7\u00f5es por ferramentas de NLP pra identificar padr\u00f5es no que os clientes sentem
  • Gera\u00e7\u00e3o de leads \u2014 encontrar neg\u00f3cios com avalia\u00e7\u00f5es p\u00e9ssimas que podem precisar do seu produto ou servi\u00e7o
  • Pesquisa de mercado \u2014 analisar tend\u00eancias de avalia\u00e7\u00f5es em toda uma ind\u00fastria
  • Trabalho acad\u00eamico \u2014 montar datasets de pesquisa sobre comportamento do consumidor

API Oficial do Google vs. Web Scraping \u2014 Qual a Diferen\u00e7a?

Antes de entrar em qualquer c\u00f3digo, tem algo que voc\u00ea precisa saber. O Google tem uma API oficial pra isso \u2014 a Places API \u2014 mas sinceramente, ela \u00e9 bem limitada pra o que a maioria das pessoas precisa.

Google Places API (O Jeito Oficial)

O problema com a API:

  • Ela s\u00f3 te d\u00e1 5 avalia\u00e7\u00f5es por neg\u00f3cio. Cinco. Esse \u00e9 o limite.
  • Custa dinheiro \u2014 cerca de $17 por 1.000 requisi\u00e7\u00f5es de Place Details
  • Voc\u00ea n\u00e3o tem acesso ao hist\u00f3rico completo de avalia\u00e7\u00f5es
  • O Google escolhe quais 5 avalia\u00e7\u00f5es te mostrar (o algoritmo deles decide, n\u00e3o voc\u00ea)
  • Por outro lado, os dados voltam como JSON limpo, ent\u00e3o o parsing \u00e9 f\u00e1cil

Web Scraping (O Que Vamos Fazer)

Scraping, por outro lado:

  • Te d\u00e1 todas as avalia\u00e7\u00f5es que um neg\u00f3cio tem \u2014 n\u00e3o s\u00f3 5
  • \u00c9 de gra\u00e7a (bom, seu tempo n\u00e3o \u00e9 de gra\u00e7a, mas as ferramentas s\u00e3o)
  • Voc\u00ea pega o hist\u00f3rico completo de avalia\u00e7\u00f5es com datas reais
  • D\u00e1 mais trabalho pra configurar, sem d\u00favida
  • E voc\u00ea vai precisar atualizar seu c\u00f3digo de vez em quando quando o Google mudar o layout da p\u00e1gina

Ent\u00e3o, se 5 avalia\u00e7\u00f5es s\u00e3o suficientes pra voc\u00ea, vai com a API. Mas se voc\u00ea precisa do panorama completo \u2014 centenas ou milhares de avalia\u00e7\u00f5es \u2014 vai precisar fazer scraping, ou usar uma ferramenta como o Livescraper que faz isso por voc\u00ea.

Pr\u00e9-requisitos \u2014 O Que Voc\u00ea Precisa Antes de Come\u00e7ar

Vamos preparar sua m\u00e1quina. Nada disso \u00e9 complicado, mas voc\u00ea precisa de algumas coisas instaladas primeiro.

1. Python 3.9 ou Superior

Abra seu terminal (ou Prompt de Comando no Windows) e verifique sua vers\u00e3o:

python --version
# You want Python 3.9 or newer. 3.12 or 3.13 is ideal in 2026.

Ainda n\u00e3o tem Python? Baixe em python.org. Se voc\u00ea est\u00e1 no Mac, brew install python tamb\u00e9m funciona.

2. Crie um Ambiente Virtual

Isso mant\u00e9m as depend\u00eancias do seu projeto separadas de todo o resto no seu sistema. Confia em mim, evita muita dor de cabe\u00e7a depois:

# Make a project folder and jump in
mkdir google-reviews-scraper
cd google-reviews-scraper

# Create the virtual environment
python -m venv venv

# Activate it
# Mac/Linux:
source venv/bin/activate
# Windows:
venv\\Scripts\\activate

3. Instale as Bibliotecas

Vamos cobrir dois m\u00e9todos abaixo. Instale o que voc\u00ea pretende usar (ou os dois, se quiser testar ambos):

# For Playwright (this is the one I'd recommend)
pip install playwright pandas
playwright install chromium

# For Selenium
pip install selenium webdriver-manager pandas beautifulsoup4

N\u00e3o se preocupe ainda com o que cada biblioteca faz \u2014 vou explicando conforme avan\u00e7amos.

M\u00e9todo 1: Scraping de Avalia\u00e7\u00f5es com Playwright (Recomendado)

Playwright \u00e9 uma ferramenta de automa\u00e7\u00e3o de navegador feita pela Microsoft. Eu prefiro ela ao Selenium pra esse tipo de trabalho porque lida melhor com p\u00e1ginas din\u00e2micas, \u00e9 mais r\u00e1pida e voc\u00ea acaba escrevendo menos c\u00f3digo repetitivo. Ela surgiu alguns anos depois do Selenium e d\u00e1 pra notar \u2014 muitas arestas foram aparadas.

Por Que Playwright ao Inv\u00e9s de Selenium?

A vers\u00e3o resumida:

  • Ele espera automaticamente. O Playwright sabe quando um elemento est\u00e1 pronto antes de tentar clicar nele. Com Selenium, voc\u00ea fica espalhando time.sleep() por todo lado e torcendo pro melhor.
  • \u00c9 genuinamente mais r\u00e1pido. A forma como ele se comunica com o navegador por baixo dos panos \u00e9 mais eficiente.
  • Seletores s\u00e3o mais flex\u00edveis. CSS, XPath, correspond\u00eancia de texto, roles ARIA \u2014 tudo embutido.
  • Mais f\u00e1cil de tornar furtivo. \u00c9 mais simples configurar pra que sites n\u00e3o te identifiquem como bot imediatamente.
  • Funciona com m\u00faltiplos navegadores. Chromium, Firefox e WebKit (motor do Safari) \u2014 todos suportados.

Passo 1: A Configura\u00e7\u00e3o B\u00e1sica

Beleza, vamos escrever um pouco de c\u00f3digo. Crie um arquivo chamado scraper.py e comece com a configura\u00e7\u00e3o do navegador:

from playwright.sync_api import sync_playwright
import pandas as pd
import time
import random
import re

def create_browser():
    """Launch a browser that looks like a real user."""
    p = sync_playwright().start()
    browser = p.chromium.launch(
        headless=False,  # Set True for production
        args=[
            '--disable-blink-features=AutomationControlled',
            '--no-sandbox',
        ]
    )
    context = browser.new_context(
        viewport={'width': 1366, 'height': 768},
        user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                   'AppleWebKit/537.36 (KHTML, like Gecko) '
                   'Chrome/124.0.0.0 Safari/537.36',
        locale='en-US',
    )
    return p, browser, context

Deixa eu explicar o que t\u00e1 acontecendo aqui. Estamos abrindo um navegador Chromium com configura\u00e7\u00f5es que fazem ele parecer uma pessoa normal navegando na web \u2014 n\u00e3o um script. A parte do headless=False significa que a janela do navegador realmente aparece na sua tela, o que \u00e9 \u00f3timo pra depura\u00e7\u00e3o porque voc\u00ea consegue ver exatamente o que t\u00e1 acontecendo. A string de user agent diz ao Google qual navegador supostamente estamos usando, e aquela flag disable-blink-features remove o sinal revelador que diz "ei, esse navegador est\u00e1 sendo controlado por software de automa\u00e7\u00e3o."

Passo 2: Navegue at\u00e9 o Neg\u00f3cio e Abra a Aba de Avalia\u00e7\u00f5es

Agora precisamos ir at\u00e9 uma p\u00e1gina de neg\u00f3cio do Google Maps e clicar na se\u00e7\u00e3o de avalia\u00e7\u00f5es. Essa parte \u00e9 simples:

def open_reviews_panel(page, place_url):
    """Navigate to a Google Maps place and open the reviews tab."""
    page.goto(place_url, wait_until='networkidle')

    # Accept cookies if prompted
    try:
        page.click('button:has-text("Accept all")', timeout=3000)
    except:
        pass

    # Wait for the page to fully load
    page.wait_for_selector('button[data-tab-index="1"]', timeout=10000)

    # Click on the "Reviews" tab
    page.click('button[data-tab-index="1"]')
    time.sleep(2)  # Let reviews load

    print("Reviews panel opened successfully")

Bem simples, n\u00e9? Vamos at\u00e9 a URL, esperamos carregar completamente, lidamos com aquele popup chato de consentimento de cookies (se voc\u00ea \u00e9 da Europa, sabe do que t\u00f4 falando), e depois clicamos na aba "Reviews". O seletor data-tab-index="1" aponta pra aba de avalia\u00e7\u00f5es \u2014 pelo menos at\u00e9 o in\u00edcio de 2026. Se o Google mudar o layout, esse seletor pode precisar de atualiza\u00e7\u00e3o.

Passo 3: Role pra Baixo pra Carregar Mais Avalia\u00e7\u00f5es

Aqui a coisa fica interessante. O Google Maps n\u00e3o carrega todas as avalia\u00e7\u00f5es de uma vez \u2014 ele mostra umas 10 e depois carrega mais conforme voc\u00ea rola pra baixo. Ent\u00e3o temos que ficar rolando e esperando, rolando e esperando, at\u00e9 pegar tudo (ou atingir nosso n\u00famero alvo):

def scroll_reviews(page, max_reviews=100):
    """Scroll the reviews panel to load more reviews."""
    scrollable = page.query_selector('div.m6QErb.DxyBCb.kA9KIf.dS8AEf')
    if not scrollable:
        print("Could not find scrollable reviews container")
        return

    last_count = 0
    scroll_attempts = 0
    max_attempts = 50

    while scroll_attempts < max_attempts:
        # Scroll down inside the reviews panel
        scrollable.evaluate('el => el.scrollTop = el.scrollHeight')

        # Wait for new reviews to load
        time.sleep(random.uniform(1.5, 3.0))

        # Count current reviews
        reviews = page.query_selector_all('div.jftiEf.fontBodyMedium')
        current_count = len(reviews)

        print(f"Loaded {current_count} reviews...")

        # Stop if we've reached our target
        if current_count >= max_reviews:
            print(f"Reached target of {max_reviews} reviews")
            break

        # Stop if no new reviews loaded (we've reached the end)
        if current_count == last_count:
            scroll_attempts += 1
            if scroll_attempts >= 3:
                print(f"No more reviews to load. Total: {current_count}")
                break
        else:
            scroll_attempts = 0

        last_count = current_count

A parte complicada aqui \u00e9 encontrar o container que rola correto \u2014 n\u00e3o \u00e9 a p\u00e1gina principal que rola, \u00e9 uma div espec\u00edfica dentro do painel de avalia\u00e7\u00f5es. Rolamos ela at\u00e9 o final com JavaScript, depois pausamos por um tempo aleat\u00f3rio (entre 1,5 e 3 segundos) pra parecer mais humano. O script continua at\u00e9 atingirmos nosso n\u00famero alvo de avalia\u00e7\u00f5es ou nenhuma nova aparecer depois de algumas tentativas.

Passo 4: Extraia os Dados das Avalia\u00e7\u00f5es

Agora que todas as avalia\u00e7\u00f5es est\u00e3o carregadas na p\u00e1gina, precisamos pegar os dados de cada uma. Essa fun\u00e7\u00e3o percorre cada elemento de avalia\u00e7\u00e3o e puxa o nome, nota, texto, data e qualquer resposta do propriet\u00e1rio:

def extract_reviews(page):
    """Extract all review data from the loaded reviews."""
    reviews_data = []
    review_elements = page.query_selector_all('div.jftiEf.fontBodyMedium')

    for element in review_elements:
        try:
            # Reviewer name
            name_el = element.query_selector('.d4r55')
            name = name_el.inner_text() if name_el else 'Anonymous'

            # Star rating
            rating_el = element.query_selector('.kvMYJc')
            rating = 0
            if rating_el:
                aria = rating_el.get_attribute('aria-label')
                match = re.search(r'(\\d+)', aria or '')
                rating = int(match.group(1)) if match else 0

            # Review text (click "More" to expand if needed)
            more_btn = element.query_selector('button.w8nwRe.kyuRq')
            if more_btn:
                try:
                    more_btn.click()
                    time.sleep(0.3)
                except:
                    pass

            text_el = element.query_selector('.wiI7pd')
            text = text_el.inner_text() if text_el else ''

            # Review date
            date_el = element.query_selector('.rsqaWe')
            date = date_el.inner_text() if date_el else ''

            # Owner response
            response_el = element.query_selector('.CDe7pd')
            owner_response = response_el.inner_text() if response_el else ''

            reviews_data.append({
                'reviewer_name': name,
                'rating': rating,
                'review_text': text,
                'review_date': date,
                'owner_response': owner_response,
            })

        except Exception as e:
            print(f"Error extracting review: {e}")
            continue

    return reviews_data

Uma coisa pra notar: algumas avalia\u00e7\u00f5es t\u00eam um bot\u00e3o "Mais" que esconde o texto completo. Tentamos clicar nesse bot\u00e3o pra expandir a avalia\u00e7\u00e3o antes de pegar o texto. Nem sempre funciona perfeitamente, mas pega a maioria.

Passo 5: Conecte Tudo

Beleza, agora vamos conectar todas essas fun\u00e7\u00f5es em um script que voc\u00ea pode realmente rodar:

def scrape_google_reviews(place_url, max_reviews=100):
    """Main function to scrape Google Maps reviews."""
    p, browser, context = create_browser()
    page = context.new_page()

    try:
        # Step 1: Open the reviews panel
        open_reviews_panel(page, place_url)

        # Step 2: Scroll to load reviews
        scroll_reviews(page, max_reviews)

        # Step 3: Extract review data
        reviews = extract_reviews(page)

        # Step 4: Save to CSV
        df = pd.DataFrame(reviews)
        filename = 'google_reviews.csv'
        df.to_csv(filename, index=False, encoding='utf-8')
        print(f"\\nSaved {len(reviews)} reviews to {filename}")
        print(f"Average rating: {df['rating'].mean():.1f} stars")

        return reviews

    finally:
        browser.close()
        p.stop()


# Run the scraper
if __name__ == '__main__':
    url = 'https://www.google.com/maps/place/YOUR_BUSINESS_URL'
    reviews = scrape_google_reviews(url, max_reviews=200)
    print(f"\\nDone! Scraped {len(reviews)} reviews")

S\u00f3 troque YOUR_BUSINESS_URL por um link real do Google Maps. V\u00e1 ao Google Maps, busque qualquer neg\u00f3cio e copie a URL da barra de endere\u00e7os do seu navegador. \u00c9 isso que vai ali.

M\u00e9todo 2: Scraping de Avalia\u00e7\u00f5es com Selenium

Talvez voc\u00ea j\u00e1 tenha usado Selenium antes e se sinta confort\u00e1vel com ele. Ou talvez seu ambiente de trabalho n\u00e3o suporte Playwright por algum motivo. Tudo bem \u2014 Selenium d\u00e1 conta do recado tamb\u00e9m. O c\u00f3digo \u00e9 um pouco mais extenso, mas a l\u00f3gica \u00e9 a mesma.

Configura\u00e7\u00e3o do Selenium

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.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
import pandas as pd
import time
import random

def create_selenium_driver():
    """Create a Selenium Chrome driver with stealth settings."""
    options = webdriver.ChromeOptions()
    options.add_argument('--disable-blink-features=AutomationControlled')
    options.add_argument('--window-size=1366,768')
    options.add_argument('--lang=en-US')
    options.add_experimental_option('excludeSwitches', ['enable-automation'])
    options.add_experimental_option('useAutomationExtension', False)

    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=options)

    # Remove the webdriver flag
    driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
        'source': '''
            Object.defineProperty(navigator, 'webdriver', {get: () => undefined})
        '''
    })

    return driver

Scraper de Avalia\u00e7\u00f5es com Selenium

def scrape_with_selenium(place_url, max_reviews=100):
    """Scrape Google Maps reviews using Selenium."""
    driver = create_selenium_driver()

    try:
        driver.get(place_url)
        time.sleep(3)

        # Accept cookies
        try:
            cookie_btn = WebDriverWait(driver, 5).until(
                EC.element_to_be_clickable((By.XPATH,
                    '//button[contains(text(), "Accept all")]'))
            )
            cookie_btn.click()
        except:
            pass

        # Click Reviews tab
        reviews_tab = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR,
                'button[data-tab-index="1"]'))
        )
        reviews_tab.click()
        time.sleep(2)

        # Scroll to load reviews
        scrollable = driver.find_element(By.CSS_SELECTOR,
            'div.m6QErb.DxyBCb.kA9KIf.dS8AEf')

        last_count = 0
        for _ in range(50):
            driver.execute_script(
                'arguments[0].scrollTop = arguments[0].scrollHeight',
                scrollable
            )
            time.sleep(random.uniform(1.5, 3.0))

            reviews = driver.find_elements(By.CSS_SELECTOR,
                'div.jftiEf.fontBodyMedium')
            if len(reviews) >= max_reviews or len(reviews) == last_count:
                break
            last_count = len(reviews)

        # Parse with BeautifulSoup for easier extraction
        soup = BeautifulSoup(driver.page_source, 'html.parser')
        review_elements = soup.select('div.jftiEf.fontBodyMedium')

        reviews_data = []
        for el in review_elements:
            name = el.select_one('.d4r55')
            rating = el.select_one('.kvMYJc')
            text = el.select_one('.wiI7pd')
            date = el.select_one('.rsqaWe')

            rating_val = 0
            if rating and rating.get('aria-label'):
                import re
                m = re.search(r'(\\d+)', rating['aria-label'])
                rating_val = int(m.group(1)) if m else 0

            reviews_data.append({
                'reviewer_name': name.text if name else 'Anonymous',
                'rating': rating_val,
                'review_text': text.text if text else '',
                'review_date': date.text if date else '',
            })

        # Save to CSV
        df = pd.DataFrame(reviews_data)
        df.to_csv('reviews_selenium.csv', index=False)
        print(f"Saved {len(reviews_data)} reviews")
        return reviews_data

    finally:
        driver.quit()

Playwright vs. Selenium \u2014 Qual Voc\u00ea Deve Escolher?

Me perguntam muito isso. Aqui est\u00e1 como eles se comparam lado a lado:

Caracter\u00edstica Playwright Selenium
VelocidadeMais r\u00e1pido (suporte async)Mais lento
Espera autom\u00e1ticaEmbutidaManual (WebDriverWait)
Facilidade de configura\u00e7\u00e3oMuito f\u00e1cilRequer gerenciamento de driver
Anti-detec\u00e7\u00e3oMelhores op\u00e7\u00f5es stealthPrecisa de undetected-chromedriver
ComunidadeCrescendo r\u00e1pidoMaior comunidade
Curva de aprendizadoModeradaSuave

Minha opini\u00e3o sincera? Se voc\u00ea t\u00e1 come\u00e7ando do zero, vai de Playwright. Voc\u00ea vai escrever menos c\u00f3digo e ter menos dor de cabe\u00e7a. Mas se j\u00e1 tem c\u00f3digo Selenium rodando em algum lugar, n\u00e3o tem motivo forte pra reescrever.

Como Evitar Ser Bloqueado pelo Google

Essa \u00e9 a parte que a maioria dos tutoriais passa por cima, mas provavelmente \u00e9 a mais importante. O Google \u00e9 muito bom em detectar bots. Se voc\u00ea simplesmente abre um navegador headless e come\u00e7a a bombardear os servidores deles, vai ser bloqueado em minutos. Veja como ficar fora do radar.

1. Adicione Pausas Aleat\u00f3rias Entre A\u00e7\u00f5es

Ningu\u00e9m clica num bot\u00e3o e instantaneamente clica em outro 50 milissegundos depois. Pessoas reais hesitam, leem coisas, se distraem. Seu scraper deveria fazer o mesmo:

import random

def human_delay(min_sec=1.0, max_sec=3.0):
    """Wait a random amount of time to mimic human behavior."""
    delay = random.uniform(min_sec, max_sec)
    time.sleep(delay)

2. Varie Seu User Agent

Se toda requisi\u00e7\u00e3o vem exatamente da mesma impress\u00e3o digital de navegador, \u00e9 uma entrega. Misture:

USER_AGENTS = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 Chrome/124.0.0.0',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/124.0.0.0',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Firefox/125.0',
]

user_agent = random.choice(USER_AGENTS)

3. Use Proxies (Especialmente pra Trabalhos Maiores)

Quando voc\u00ea come\u00e7a a fazer scraping de mais do que uns poucos neg\u00f3cios, vai querer rotacionar seu endere\u00e7o IP. Caso contr\u00e1rio, o Google v\u00ea centenas de requisi\u00e7\u00f5es vindo de um s\u00f3 lugar e te derruba:

def create_browser_with_proxy(proxy_url):
    """Launch browser through a proxy server."""
    p = sync_playwright().start()
    browser = p.chromium.launch(
        proxy={'server': proxy_url},
        headless=True,
    )
    return p, browser

4. N\u00e3o Seja Ganancioso com a Velocidade

Eu sei que \u00e9 tentador fazer scraping o mais r\u00e1pido poss\u00edvel, mas paci\u00eancia compensa aqui. Algumas diretrizes que funcionaram pra mim:

  • Fique em torno de 10-20 neg\u00f3cios por hora de um \u00fanico endere\u00e7o IP
  • Espere 3-5 segundos entre carregar p\u00e1ginas de neg\u00f3cios diferentes
  • Pause 1-3 segundos entre a\u00e7\u00f5es de rolagem dentro do painel de avalia\u00e7\u00f5es
  • A cada 10-15 neg\u00f3cios, fa\u00e7a uma pausa mais longa \u2014 tipo 30-60 segundos. Vai pegar um caf\u00e9 ou algo assim.

Problemas Comuns (e Como Resolver)

Voc\u00ea vai encontrar problemas. Todo mundo encontra. Aqui est\u00e3o os que mais aparecem:

"As avalia\u00e7\u00f5es n\u00e3o est\u00e3o carregando"

Isso geralmente significa que o Google percebeu que voc\u00ea \u00e9 um bot, ou mudou algo no layout da p\u00e1gina. Primeira coisa a tentar: coloque headless=False pra voc\u00ea poder ver a janela do navegador. Tem um CAPTCHA? Um banner de cookies bloqueando tudo? \u00c0s vezes a solu\u00e7\u00e3o \u00e9 simples como clicar em "Aceitar" num popup que voc\u00ea n\u00e3o previu. Outras vezes, o Google mudou as classes CSS e voc\u00ea vai precisar atualizar seus seletores.

"S\u00f3 estou pegando 10 avalia\u00e7\u00f5es mesmo tendo centenas"

A rolagem n\u00e3o t\u00e1 funcionando direito. Confira se voc\u00ea t\u00e1 rolando dentro do container correto \u2014 \u00e9 uma div espec\u00edfica dentro do painel de avalia\u00e7\u00f5es, n\u00e3o a p\u00e1gina principal. Adicione um print(scrollable) pra ter certeza que n\u00e3o \u00e9 None. Tamb\u00e9m tente aumentar o delay entre as rolagens \u2014 \u00e0s vezes os servidores do Google demoram pra enviar o pr\u00f3ximo lote de avalia\u00e7\u00f5es.

"Funciona pra 3-4 neg\u00f3cios e depois sou bloqueado"

Voc\u00ea t\u00e1 indo r\u00e1pido demais. Diminua a velocidade, adicione pausas mais longas entre neg\u00f3cios, e considere seriamente usar proxies se ainda n\u00e3o usa. Dez a vinte neg\u00f3cios por sess\u00e3o de um IP \u00e9 um alvo razo\u00e1vel.

"Os seletores n\u00e3o est\u00e3o encontrando nada"

O Google muda os nomes das classes CSS com mais frequ\u00eancia do que voc\u00ea imagina. Quando isso acontece, abra o Google Maps no seu pr\u00f3prio navegador, clique com o bot\u00e3o direito numa avalia\u00e7\u00e3o, clique em "Inspecionar Elemento" e veja os nomes de classes atuais. Depois atualize seu c\u00f3digo pra bater. \u00c9 chato, mas faz parte do jogo do web scraping.

Ou Simplesmente Pule o C\u00f3digo \u2014 Use o Livescraper

Olha, eu acabei de gastar uma boa parte desse artigo te ensinando a construir um scraper do zero. E tudo acima funciona. Mas eu estaria mentindo se dissesse que \u00e9 zero manuten\u00e7\u00e3o. O Google muda o layout da p\u00e1gina, seus seletores quebram. Eles lan\u00e7am novas medidas anti-bot, seus proxies param de funcionar. Voc\u00ea conserta uma coisa e outra quebra. \u00c9 um ciclo.

Se voc\u00ea s\u00f3 quer os dados sem lidar com tudo isso, \u00e9 exatamente pra isso que o Scraper de Avalia\u00e7\u00f5es do Livescraper serve.

Por Que Usar o Livescraper ao Inv\u00e9s de Construir o Seu?

Caracter\u00edstica Scraper Python DIY Livescraper
Tempo de configura\u00e7\u00e3oHoras a dias2 minutos
Manuten\u00e7\u00e3oConstante (seletores quebram)Zero \u2014 a gente cuida
Anti-detec\u00e7\u00e3oVoc\u00ea gerencia proxies e delaysRota\u00e7\u00e3o de proxy embutida
EscalaLimitada pela sua m\u00e1quinaBaseado em nuvem, ilimitado
Formato de sa\u00eddaCSV (exporta\u00e7\u00e3o manual)CSV, JSON, Excel
Programa\u00e7\u00e3o necess\u00e1riaSim (Python)N\u00e3o
CustoGr\u00e1tis + seu tempoPlano gratuito dispon\u00edvel

Como Funciona (S\u00e9rio, S\u00e3o 3 Passos)

  1. Crie uma conta \u2014 v\u00e1 at\u00e9 app.livescraper.com e se cadastre. \u00c9 gr\u00e1tis pra come\u00e7ar.
  2. Diga o que quer raspar \u2014 cole a URL do Google Maps ou simplesmente digite o nome do neg\u00f3cio. Escolha "Reviews Scraper" como tipo de tarefa.
  3. Pegue seu arquivo \u2014 clique em "Start Scraping" e baixe os resultados como CSV ou JSON quando terminar.

Sem ambiente Python pra configurar, sem proxies pra comprar, sem seletores pra consertar quando quebram. Voc\u00ea simplesmente pega os dados. Eu sei que parece papo de venda, mas quando voc\u00ea j\u00e1 passou horas depurando um scraper \u00e0s 2 da manh\u00e3 porque o Google mudou uma classe CSS... voc\u00ea come\u00e7a a valorizar a simplicidade.

O Que Mais Voc\u00ea Pode Fazer Com o Livescraper?

Avalia\u00e7\u00f5es n\u00e3o s\u00e3o a \u00fanica coisa. Se voc\u00ea j\u00e1 t\u00e1 puxando dados de avalia\u00e7\u00f5es, chances s\u00e3o que precisa de outros dados de neg\u00f3cios tamb\u00e9m:

  • Google Maps Scraper \u2014 pegue nomes de neg\u00f3cios, endere\u00e7os, telefones, sites, notas de qualquer busca no Maps
  • Email Scraper \u2014 extraia endere\u00e7os de e-mail de sites de neg\u00f3cios (\u00f3timo pra prospec\u00e7\u00e3o)
  • Google Search Scraper \u2014 extraia URLs, t\u00edtulos e snippets dos resultados de busca do Google
  • Banco de Dados de Leads B2B \u2014 um banco de dados pr\u00e9-constru\u00eddo de leads de neg\u00f3cios com informa\u00e7\u00f5es de contato verificadas, sem precisar de scraping

Uma Palavra R\u00e1pida Sobre Legalidade

N\u00e3o sou advogado, ent\u00e3o isso n\u00e3o \u00e9 aconselhamento jur\u00eddico. Mas aqui vai o que geralmente se entende sobre fazer scraping de dados publicamente dispon\u00edveis como avalia\u00e7\u00f5es do Google.

Provavelmente Voc\u00ea T\u00e1 de Boa Se...

  • Est\u00e1 fazendo scraping de dados p\u00fablicos de avalia\u00e7\u00f5es pra sua pr\u00f3pria pesquisa ou an\u00e1lise
  • Est\u00e1 puxando avalia\u00e7\u00f5es do seu pr\u00f3prio neg\u00f3cio em massa
  • Est\u00e1 fazendo pesquisa acad\u00eamica com dados devidamente anonimizados
  • Est\u00e1 fazendo an\u00e1lise competitiva pra decis\u00f5es internas de neg\u00f3cio

Cuidado Se Voc\u00ea...

  • Est\u00e1 copiando avalia\u00e7\u00f5es e republicando no seu pr\u00f3prio site
  • Est\u00e1 fazendo scraping t\u00e3o agressivamente que basicamente t\u00e1 fazendo DDoS nos servidores do Google
  • Est\u00e1 armazenando informa\u00e7\u00f5es pessoais de avaliadores sem pensar em LGPD, GDPR ou leis de privacidade
  • Est\u00e1 usando os dados pra mirar ou assediar avaliadores espec\u00edficos (\u00f3bvio, n\u00e3o fa\u00e7a isso)

Bons H\u00e1bitos Gerais

  • D\u00ea uma olhada no robots.txt antes de come\u00e7ar \u2014 ele diz o que o dono do site prefere
  • Mantenha sua taxa de requisi\u00e7\u00f5es razo\u00e1vel
  • N\u00e3o guarde dados pessoais por mais tempo do que realmente precisa
  • Fique em usos leg\u00edtimos de neg\u00f3cio
  • Se compliance \u00e9 uma preocupa\u00e7\u00e3o, um servi\u00e7o como o Livescraper cuida de boa parte disso pra voc\u00ea

Conclus\u00e3o

Cobrimos muita coisa, mas agora voc\u00ea deve ter uma compreens\u00e3o bem s\u00f3lida de como fazer scraping de avalia\u00e7\u00f5es do Google Maps com Python. Passamos pela abordagem completa com Playwright (que eu escolheria pra qualquer projeto novo), a abordagem com Selenium (perfeitamente v\u00e1lida se \u00e9 o que voc\u00ea conhece), truques anti-detec\u00e7\u00e3o e solu\u00e7\u00f5es pras dores de cabe\u00e7a mais comuns.

A realidade \u00e9 que construir um scraper \u00e9 a parte f\u00e1cil. Manter ele rodando de forma confi\u00e1vel ao longo do tempo \u2014 lidando com as mudan\u00e7as constantes do Google, gerenciando proxies, consertando seletores quebrados \u2014 \u00e9 onde est\u00e1 o real investimento de tempo. Ent\u00e3o dependendo das suas necessidades, pode fazer sentido usar uma ferramenta que cuida de tudo isso nos bastidores.

Se isso parece atraente, experimente o Livescraper. Tem um plano gratuito pra voc\u00ea testar sem compromisso. E se preferir o caminho DIY, o c\u00f3digo acima tem tudo que voc\u00ea precisa pra come\u00e7ar. Boa sorte com seu projeto!