Scraping de Dados do Google Maps: Listagens e Avaliacoes de Negocios

Saiba como raspar Google Maps para dados de negócios, incluindo nomes, endereços, avaliações e avaliações. Cobre a comparação API vs raspagem, estratégias proxy e exemplos de código em Python e Node.js.

Scraping de Dados do Google Maps: Listagens e Avaliacoes de Negocios

Por que raspar dados do Google Maps?

Google Maps contém o banco de dados mais abrangente de empresas locais no mundo. Com mais de 200 milhões de empresas listadas, inclui nomes, endereços, números de telefone, sites, avaliações, avaliações, horas operacionais e fotos — todas estruturadas e pesquisáveis.

Extrair estes dados programáticamente permite aplicações de negócios valiosas:

  • Geração de chumbo: Criar listas específicas de empresas por indústria e localização
  • Análise competitiva: Mapa localização do concorrente, avaliações e opinião
  • Investigação de mercado: Compreender a densidade de negócios, padrões de preços e cobertura de serviços por área
  • Auditoria local do SEO: Verifique suas listas de negócios e compare com concorrentes
  • Enriquecimento dos dados: Suplemento de dados CRM com novas informações comerciais

Este guia abrange as abordagens técnicas para extrair dados do Google Maps usando proxies. Para estratégias mais amplas de raspagem SERP, consulte raspagem SERP completa com guia proxies.

Google coloca API vs raspagem

Antes de construir um raspador, considere se a API oficial do Google Places atende às suas necessidades.

Google coloca API vs raspagem
FatorColocar APISucata
Custo$17 por 1.000 pedidos (após nível livre)Largura de banda proxy somente (~$0.10-0.50 por 1.000 páginas)
Campos de dadosJSON estruturado, 20+ camposTodos os dados visíveis, incluindo texto de revisões
Limites de taxaLimites rigorosos por segundo e diáriosLimitado pelo tamanho do conjunto de proxy
Texto de revisãoAté 5 revisões mais relevantesTodos os comentários (com paginação)
ConfiabilidadeObjetivos oficiais e estáveisRequer manutenção do analisador
Termos de ServiçoTotalmente compatívelVerifique as regras locais e para o S.O.
EscalaCaro na escalaCusto-efetivo em volumes elevados
A API Places é a melhor escolha para aplicações críticas à produção em pequena escala. A raspagem é mais econômica quando você precisa de grandes conjuntos de dados, texto de revisão completo ou quando os custos da API se tornam proibitivos.

Estrutura de URL do Google Maps

Compreender padrões de URL do Google Maps é essencial para a construção de um raspador. Existem dois pontos de entrada principais:

Resultados da Pesquisa

Os resultados da pesquisa do Google Maps podem ser acessados através:

# Browser URL format
https://www.google.com/maps/search/restaurants+near+new+york
# URL parameters for search
https://www.google.com/maps/search/{query}/@{lat},{lng},{zoom}z

Detalhes do lugar

Páginas de negócios individuais seguem este padrão:

# Place detail URL
https://www.google.com/maps/place/{business+name}/@{lat},{lng},{zoom}z/data=!{place_id}

Construindo um Google Maps Scraper

Google Maps é um aplicativo com peso JavaScript. Ao contrário do Google Search regular, solicitações HTTP simples muitas vezes retornam dados incompletos. Existem duas abordagens: analisar os dados JSON incorporados da fonte da página, ou usar um navegador sem cabeça.

Abordagem 1: Analisando JSON Incorporado (Mais rápido)

As páginas do Google Maps contêm dados estruturados incorporados na fonte HTML. Aqui está como extraí-lo:

import requests
import json
import re
import time
import random
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
def search_google_maps(query, location="us"):
    """Search Google Maps and extract business listings."""
    proxies = {"http": PROXY_URL, "https": PROXY_URL}
    headers = {
        "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",
        "Accept-Language": "en-US,en;q=0.9",
        "Accept": "text/html,application/xhtml+xml",
    }
    # Use the search URL format
    search_url = f"https://www.google.com/maps/search/{query.replace(' ', '+')}"
    response = requests.get(
        search_url,
        headers=headers,
        proxies=proxies,
        timeout=20,
    )
    response.raise_for_status()
    # Extract embedded JSON data from the page
    # Google Maps embeds data in a specific pattern
    businesses = []
    # Look for business data patterns in the response
    # The data is typically in a JavaScript variable
    patterns = re.findall(r'\["([^"]+)",null,null,null,null,null,null,null,"([^"]*)"', response.text)
    # Alternative: parse the structured search results
    # Google Maps returns data in protobuf-like JSON arrays
    json_matches = re.findall(r'null,\["([^"]{5,80})"[^]]*?"([^"]*?(?:St|Ave|Rd|Blvd|Dr|Ln)[^"]*?)"', response.text)
    for match in json_matches[:20]:
        businesses.append({
            "name": match[0],
            "address": match[1] if len(match) > 1 else "",
        })
    return businesses
results = search_google_maps("restaurants near Times Square New York")
for b in results:
    print(f"{b['name']} - {b['address']}")

Abordagem 2: Navegador sem cabeça (mais confiável)

Para extração mais confiável, use um navegador sem cabeça que renderize JavaScript:

from playwright.sync_api import sync_playwright
import json
import time
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
def scrape_maps_with_browser(query):
    """Use Playwright to scrape Google Maps with full JS rendering."""
    with sync_playwright() as p:
        browser = p.chromium.launch(
            headless=True,
            proxy={
                "server": "http://gate.proxyhat.com:8080",
                "username": "USERNAME",
                "password": "PASSWORD",
            },
        )
        page = browser.new_page()
        page.set_extra_http_headers({
            "Accept-Language": "en-US,en;q=0.9",
        })
        # Navigate to Google Maps search
        search_url = f"https://www.google.com/maps/search/{query.replace(' ', '+')}"
        page.goto(search_url, wait_until="networkidle", timeout=30000)
        # Wait for results to load
        page.wait_for_selector('div[role="feed"]', timeout=10000)
        # Scroll to load more results
        feed = page.query_selector('div[role="feed"]')
        for _ in range(5):
            feed.evaluate("el => el.scrollBy(0, 1000)")
            time.sleep(1.5)
        # Extract business data from the results
        businesses = []
        items = page.query_selector_all('div[role="feed"] > div > div > a')
        for item in items:
            name = item.get_attribute("aria-label")
            href = item.get_attribute("href")
            if name and href:
                businesses.append({
                    "name": name,
                    "url": href,
                })
        browser.close()
        return businesses
results = scrape_maps_with_browser("coffee shops in San Francisco")
for b in results:
    print(f"{b['name']}")
    print(f"  {b['url'][:80]}...")
    print()

Extraindo detalhes de negócios

Depois de ter uma lista de URLs de negócios, extraia informações detalhadas de cada listagem:

import requests
import re
import json
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
def extract_business_details(maps_url):
    """Extract detailed business info from a Google Maps place page."""
    proxies = {"http": PROXY_URL, "https": PROXY_URL}
    headers = {
        "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",
        "Accept-Language": "en-US,en;q=0.9",
    }
    response = requests.get(maps_url, headers=headers, proxies=proxies, timeout=20)
    text = response.text
    business = {}
    # Extract business name
    name_match = re.search(r'

Estratégia de Proxy para Google Maps

O Google Maps tem suas próprias proteções anti-bot que exigem uma estratégia de proxy personalizada.

Por que as Proxies Residenciais são necessárias

Google Maps é particularmente agressivo sobre o bloqueio de IPs datacenter. O aplicativo carrega dados através de várias chamadas de API, e o Google cruza referências do IP em todas essas solicitações. Proxies residenciais de ProxyHat são essenciais porque:

  • Eles passam cheques de reputação IP que Maps API chama de força
  • Eles suportam geo-segmentação de nível municipal para pesquisas específicas de localização
  • Eles mantêm o comportamento consistente da sessão que Maps espera

Gerenciamento de Sessão

Ao contrário de raspagem SERP regular onde você gira IPs por solicitação, Google Maps funciona melhor com sessões pegajosas:

# For Google Maps, use sticky sessions (same IP for a business detail page)
# ProxyHat supports session-based rotation via the proxy URL
# See docs.proxyhat.com for session configuration
# Rotating IP (for search listings)
ROTATING_PROXY = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
# Sticky session (for individual place pages)
# Same session ID = same IP for the session duration
STICKY_PROXY = "http://USERNAME-session-maps123:PASSWORD@gate.proxyhat.com:8080"

Limitação da Taxa

O Google Maps é mais sensível a pedidos rápidos do que a pesquisa regular do Google. Siga estas orientações:

  • Aguarde 5-10 segundos entre as páginas de resultado da pesquisa
  • Aguarde 3-5 segundos entre cargas individuais de página de lugar
  • Limitar as solicitações simultâneas para evitar padrões de ruptura
  • Usar atrasos mais longos para revisão paginação (8-15 segundos entre páginas)

Implementação Node.js

const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const agent = new HttpsProxyAgent('http://USERNAME:PASSWORD@gate.proxyhat.com:8080');
async function searchGoogleMaps(query) {
  const searchUrl = `https://www.google.com/maps/search/${encodeURIComponent(query)}`;
  const { data } = await axios.get(searchUrl, {
    headers: {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
      'Accept-Language': 'en-US,en;q=0.9',
    },
    httpsAgent: agent,
    timeout: 20000,
  });
  // Extract business names from the response
  const businesses = [];
  const namePattern = /\["([^"]{3,80})",null,null,null,null,null,null,null/g;
  let match;
  while ((match = namePattern.exec(data)) !== null) {
    businesses.push({ name: match[1] });
  }
  return businesses;
}
async function main() {
  const results = await searchGoogleMaps('plumbers in Chicago');
  console.log(`Found ${results.length} businesses:`);
  results.forEach((b, i) => console.log(`${i + 1}. ${b.name}`));
}
main().catch(console.error);

Extraindo Comentários em Escala

As revisões do Google Maps estão entre os pontos de dados mais valiosos. Cada revisão inclui o nome do revisor, classificação, texto, data e às vezes fotos.

import requests
import re
import json
import time
import random
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
def extract_reviews(place_id, num_reviews=50):
    """Extract reviews for a Google Maps place using the internal API."""
    proxies = {"http": PROXY_URL, "https": PROXY_URL}
    headers = {
        "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",
        "Accept-Language": "en-US,en;q=0.9",
    }
    reviews = []
    # Google Maps loads reviews via AJAX with pagination tokens
    # The first page is loaded with the place page
    maps_url = f"https://www.google.com/maps/place/?q=place_id:{place_id}"
    response = requests.get(maps_url, headers=headers, proxies=proxies, timeout=20)
    # Extract review data from embedded JSON
    # Reviews are typically in arrays with rating, text, and author
    review_pattern = re.findall(
        r'"(\d)","([^"]{10,500})"[^]]*?"([^"]{2,50})"',
        response.text
    )
    for match in review_pattern[:num_reviews]:
        reviews.append({
            "rating": int(match[0]),
            "text": match[1],
            "author": match[2],
        })
    return reviews
# Example: extract reviews
reviews = extract_reviews("ChIJN1t_tDeuEmsRUsoyG83frY4")  # Example place ID
for r in reviews[:5]:
    print(f"{'*' * r['rating']} by {r['author']}")
    print(f"  {r['text'][:100]}...")
    print()

Estruturação e Armazenamento de Dados

Organize os dados raspados do Google Maps em um formato estruturado para análise:

import json
import csv
from datetime import datetime
def save_businesses(businesses, output_format="json"):
    """Save scraped business data in structured format."""
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    if output_format == "json":
        filename = f"maps_data_{timestamp}.json"
        with open(filename, "w") as f:
            json.dump(businesses, f, indent=2, ensure_ascii=False)
    elif output_format == "csv":
        filename = f"maps_data_{timestamp}.csv"
        if businesses:
            keys = businesses[0].keys()
            with open(filename, "w", newline="", encoding="utf-8") as f:
                writer = csv.DictWriter(f, fieldnames=keys)
                writer.writeheader()
                writer.writerows(businesses)
    print(f"Saved {len(businesses)} businesses to {filename}")
    return filename

Considerações Legal e Ética

Raspar dados do Google Maps levanta importantes questões legais e éticas:

  • Termos de Serviço do Google: Os ToS do Google proíbem raspagem automatizada. Considere usar a API oficial dos Locais para aplicações de produção
  • Protecção de dados: Dados de negócios como números de telefone e endereços podem estar sujeitos a regulamentos de proteção de dados em algumas jurisdições
  • Limitação da taxa: Mesmo com proxies, seja respeitoso com a infraestrutura do Google. Excesso de raspagem afeta a qualidade do serviço
  • Frescura dos dados: Sempre timestamp seus dados e atualizá-lo regularmente, como as informações de negócios mudam frequentemente
Para aplicações críticas à missão, considere combinar a API oficial Places para dados principais com raspagem direcionada para campos suplementares, como texto de revisão. Esta abordagem híbrida equilibra o cumprimento da completude dos dados.

Para mais na web raspando melhores práticas, consulte o nosso guia completo para web raspando proxies, e aprender sobre evitar blocos em nosso guia antibloqueamentoConsultar Documentação do ProxyHat para detalhes de configuração do proxy.

Pronto para começar?

Acesse mais de 50M de IPs residenciais em mais de 148 países com filtragem por IA.

Ver preçosProxies residenciais
← Voltar ao Blog