Extrair dados do Google Maps com JavaScript: Guia completo
Google Maps contém mais de 5M de fichas comerciais. Cada ficha = endereço, telefone, avaliações, horários, fotos, site. É uma mina de ouro para prospecção, pesquisa de mercado, análise competitiva.
Mas como extrair esses dados em grande escala? Existem três abordagens: a API oficial do Google Maps, scraping personalizado em JavaScript ou uma ferramenta dedicada. Este artigo cobre todas as três — com seus custos reais, limites e quando usar cada uma.
Por que extrair dados do Google Maps?
Antes de entrar na técnica, esclareça sua necessidade. Os casos de uso não são os mesmos.
Prospecção comercial
Uma agência de limpeza quer encontrar 500 restaurantes em um raio de 10 km. Ela exporta: nome, endereço, telefone, email. Ela faz chamadas frias direcionadas.
Necessidade: dados básicos (nome, contato), rapidez, volume médio.
Análise competitiva
Um restaurador analisa 50 restaurantes concorrentes: avaliações do Google, número de avaliações, horários, preços (via site), fotos, tecnologias utilizadas (eles usam Uber Eats? Deliveroo? Seu próprio site?).
Necessidade: dados enriquecidos (avaliações, stack tecnológico), contexto, volume baixo a médio.
Pesquisa de mercado
Um franqueador analisa mais de 1.000 cabeleireiros na França para identificar áreas mal atendidas. Ele extrai: localização, nota do Google, número de avaliações, horários, ficha reivindicada ou não.
Necessidade: dados estruturados, filtragem avançada, volume alto, atualização mensal.
Detecção de leads qualificados
Uma agência de SEO busca restaurantes com nota < 3 estrelas (clientes potenciais insatisfeitos). Ela exporta aqueles com 50+ avaliações (tamanho significativo) e site sem Google Analytics.
Necessidade: avaliações do Google (texto + nota + data), detecção de tecnologias, filtros complexos, volume médio.
Cada caso de uso envolve uma abordagem diferente. Vamos ver as opções.
Opção 1: A API oficial do Google Maps JavaScript
O Google oferece uma API JavaScript gratuita (com limites). Ela funciona no navegador ou em Node.js no lado do servidor.
Funcionalidades básicas
A API do Google Maps JavaScript permite 3 coisas principais:
- Geocodificação: converter um endereço → coordenadas GPS
- Places API: buscar lugares (restaurantes, encanadores, etc.) ao redor de uma posição
- Detalhes do Lugar: recuperar informações detalhadas de um lugar (avaliações, horários, fotos, URL, etc.)
Etapa 1: Obter uma chave API
- Vá para Google Cloud Console
- Crie um projeto
- Ative essas APIs: - Maps JavaScript API - Places API - Geocoding API
- Crie uma chave API (tipo: chave de navegador ou servidor, dependendo do seu uso)
- Configure as restrições (domínios permitidos, limites)
Importante: O Google cobra além dos limites gratuitos. Por padrão: 25.000 chamadas/dia gratuitas para Places, depois €0,017 por chamada.
Etapa 2: Implementar a Geocodificação
Converter um endereço em latitude/longitude.
const geocoder = new google.maps.Geocoder();
geocoder.geocode(
{ address: '75 Rue de Rivoli, Paris' },
(results, status) => {
if (status === 'OK') {
const lat = results[0].geometry.location.lat();
const lng = results[0].geometry.location.lng();
console.log(`Coordenadas: ${lat}, ${lng}`);
} else {
console.error(`Erro: ${status}`);
}
}
);
Etapa 3: Buscar lugares próximos (Nearby Search)
Encontrar todos os restaurantes em um raio de 5 km ao redor de Paris.
const map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 48.8566, lng: 2.3522 }, // Paris
zoom: 15
});
const service = new google.maps.places.PlacesService(map);
const request = {
location: new google.maps.LatLng(48.8566, 2.3522),
radius: 5000, // 5 km
type: 'restaurant',
keyword: 'pizza' // Opcional: filtrar por palavra-chave
};
service.nearbySearch(request, (results, status) => {
if (status === google.maps.places.PlacesServiceStatus.OK) {
results.forEach(place => {
console.log(`${place.name} - ${place.vicinity}`);
});
}
});
Limitação importante: nearbySearch() retorna máx. 60 resultados por requisição, com paginação. Para obter 500 restaurantes, você deve fazer 9 requisições.
Etapa 4: Recuperar os detalhes completos (Place Details)
Cada lugar retornado por nearbySearch() tem um place_id. Use-o para obter os detalhes completos.
const request = {
placeId: 'ChIJIQBpAG2ahYAR_6128GltTXQ', // Exemplo: Torre Eiffel
fields: [
'name',
'formatted_address',
'formatted_phone_number',
'website',
'opening_hours',
'reviews',
'rating',
'user_ratings_total',
'photos'
]
};
service.getDetails(request, (place, status) => {
if (status === google.maps.places.PlacesServiceStatus.OK) {
console.log(`Nome: ${place.name}`);
console.log(`Endereço: ${place.formatted_address}`);
console.log(`Telefone: ${place.formatted_phone_number}`);
console.log(`Site: ${place.website}`);
console.log(`Nota: ${place.rating} (${place.user_ratings_total} avaliações)`);
console.log(`Horários:`, place.opening_hours.weekday_text);
// Avaliações do Google
place.reviews.forEach(review => {
console.log(`${review.author_name}: ${review.rating}/5 - "${review.text}"`);
});
}
});
Custos reais da API do Google Maps
| Operação | Quota gratuita | Preço além |
|---|---|---|
| Geocodificação | 25.000/dia | €0,005 por chamada |
| Nearby Search | 25.000/dia | €0,032 por chamada |
| Place Details | 25.000/dia | €0,017 por chamada |
| Text Search | 25.000/dia | €0,032 por chamada |
Exemplo real: extrair 1.000 restaurantes com detalhes completos.
- 1.000 Nearby Search = 17 chamadas (60 resultados/chamada máx) = €0,54
- 1.000 Place Details = €17
Total: ~€17,50 por 1.000 restaurantes.
Parece pouco, mas: - Você precisa fazer isso todo mês para as atualizações - Você está limitado a 60 resultados por requisição (difícil de paginar) - As avaliações do Google retornadas são limitadas (máx. 5 por lugar) - Você não obtém as tecnologias detectadas (WordPress, Shopify, etc.)
Limites da API do Google Maps JavaScript
| Limitação | Impacto |
|---|---|
| Máx. 60 resultados por requisição | Paginamento manual complexo |
| Máx. 5 avaliações por lugar | Sem análise completa das avaliações |
| Sem filtragem por nota do Google | Você recupera todos os resultados |
| Sem filtragem por número de avaliações | Sem direcionamento para as fichas "maduras" |
| Sem detecção de tecnologias | Você não sabe se o site usa WordPress, Shopify, etc. |
| Sem dados SIRET (França) | Sem enriquecimento jurídico/financeiro |
| Quotas limitadas | Custos que sobem rapidamente em grande escala |
Opção 2: Web scraping JavaScript personalizado com Puppeteer
Se você quer contornar os limites da API oficial, pode fazer scraping diretamente do site do Google Maps com Puppeteer (uma biblioteca Node.js que automatiza um navegador Chrome).
Por que Puppeteer?
Puppeteer inicia um navegador Chrome automatizado, vai para o Google Maps, simula cliques/rolagens e extrai o HTML. Assim, você pode recuperar mais de 60 resultados, as avaliações completas, fotos, etc.
Instalação
npm install puppeteer
Exemplo: Scraper os restaurantes de Paris
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Ir para o Google Maps
await page.goto('https://www.google.com/maps/search/restaurants+paris', {
waitUntil: 'networkidle2'
});
// Aguardar o carregamento dos resultados
await page.waitForSelector('[role="listitem"]');
// Rolar para carregar mais resultados
const resultsContainer = await page.$('[role="main"]');
for (let i = 0; i < 5; i++) {
await resultsContainer.evaluate(el => {
el.scrollTop = el.scrollHeight;
});
await page.waitForTimeout(1000); // Aguardar o carregamento
}
// Extrair os dados
const restaurants = await page.evaluate(() => {
const items = document.querySelectorAll('[role="listitem"]');
return Array.from(items).map(item => {
const nameEl = item.querySelector('[role="heading"]');
const ratingEl = item.querySelector('[aria-label*="estrela"]');
const addressEl = item.querySelector('[data-item-id*="address"]');
return {
name: nameEl ? nameEl.textContent : 'N/A',
rating: ratingEl ? ratingEl.getAttribute('aria-label') : 'N/A',
address: addressEl ? addressEl.textContent : 'N/A'
};
});
});
console.log(restaurants);
await browser.close();
})();
Problemas com essa abordagem
-
Google bloqueia rapidamente: Após 10-20 requisições, o Google detecta o scraping e pede para você confirmar que não é um robô (CAPTCHA).
-
Manutenção constante: O Google muda seu HTML regularmente. Seu código quebra a cada 2-3 meses.
-
Lento: Puppeteer precisa iniciar um navegador completo para cada pesquisa. Scraping de 10.000 restaurantes = 10.000 navegadores iniciados = horas de execução.
-
Caro em recursos: Cada navegador consome 100-200 MB de RAM. Scraping em paralelo = servidor potente necessário.
-
Contra os termos de uso: O Google proíbe explicitamente o scraping do Maps.
Veredicto: Puppeteer funciona para testes pontuais (50-100 resultados), não para uma extração em grande escala.
Opção 3: Utilizar uma ferramenta dedicada (sem código)
Esta é a solução mais pragmática para 95% dos casos de uso. Em vez de codificar, você usa uma ferramenta que:
- Gerencia a extração em grande escala
- Contorna os bloqueios do Google
- Retorna os dados estruturados (CSV, JSON, API)
- Inclui as avaliações completas do Google
- Detecta as tecnologias utilizadas
- Atualiza os dados mensalmente
Por que uma ferramenta dedicada?
| Critério | API do Google | Puppeteer | Ferramenta dedicada |
|---|---|---|---|
| Custo para 10.000 resultados | €170+ | Gratuito (mas lento) | €44-99/mês |
| Tempo para 10.000 resultados | 2-3 dias (limites) | 4-6 horas | 5 minutos |
| Avaliações completas do Google | Máx. 5 por lugar | Sim | Sim |
| Filtragem por nota do Google | Não | Não | Sim |
| Detecção de tecnologias | Não | Não | Sim |
| Manutenção | Alta (mudanças na API) | Alta (mudanças no HTML) | Zero |
| Bloqueio do Google | Raro | Frequentemente | Nunca |
Casos de uso práticos com JavaScript
Aqui estão 3 cenários reais e como implementá-los.
Caso 1: Buscar 50 encanadores em Lyon com a API do Google Maps
Necessidade: nome, endereço, telefone, site, nota. Volume baixo. Orçamento limitado.
Solução: API oficial do Google Maps.
async function findPlumbers(city, limit = 50) {
const geocoder = new google.maps.Geocoder();
// Geocodificar a cidade
const cityCoords = await new Promise((resolve) => {
geocoder.geocode({ address: city }, (results) => {
resolve(results[0].geometry.location);
});
});
const map = new google.maps.Map(document.getElementById('map'), {
center: cityCoords,
zoom: 12
});
const service = new google.maps.places.PlacesService(map);
const allResults = [];
// Fazer várias requisições (máx. 60 por requisição)
for (let i = 0; i < Math.ceil(limit / 60); i++) {
const results = await new Promise((resolve) => {
service.nearbySearch(
{
location: cityCoords,
radius: 15000,
type: 'plumber',
pageToken: i === 0 ? null : nextPageToken
},
(results, status, pagination) => {
nextPageToken = pagination.nextPage ? pagination.nextPageToken : null;
resolve(results || []);
}
);
});
allResults.push(...results);
if (allResults.length >= limit) break;
}
// Recuperar os detalhes para cada resultado
const details = await Promise.all(
allResults.slice(0, limit).map(place => {
return new Promise((resolve) => {
service.getDetails(
{
placeId: place.place_id,
fields: ['name', 'formatted_address', 'formatted_phone_number', 'website', 'rating']
},
(place) => resolve(place)
);
});
})
);
return details.map(p => ({
name: p.name,
address: p.formatted_address,
phone: p.formatted_phone_number,
website: p.website,
rating: p.rating
}));
}
// Uso
findPlumbers('Lyon').then(plumbers => {
console.table(plumbers);
// Exportar para CSV
downloadCSV(plumbers);
});
Custo: ~€0,50 (17 requisições Nearby + 50 Place Details)
Tempo: 30 segundos
Limitação: Você não sabe quais são reivindicadas, quantas avaliações têm ou se usam um site customizado/Wix/Squarespace.
Caso 2: Analisar 200 restaurantes concorrentes (avaliações, tecnologias)
Necessidade: avaliações completas, nota, número de avaliações, tecnologias utilizadas. Volume médio. Orçamento médio.
Solução: Ferramenta dedicada (a API do Google Maps fornece apenas 5 avaliações no máximo).
Com uma ferramenta, você exporta em 5 minutos:
Nome,Endereço,Nota,Número de avaliações,Avaliações (texto),Avaliações (data),Avaliações (autor),Site,Technologias detectadas
Le Jules Verne,5 Rue Eiffel,4.8,1250,"Excelente relação qualidade/preço",2024-01-15,Pierre M.,lejulesverne.fr,"WordPress, WooCommerce, Google Analytics"
Septime,80 Rue Charonne,4.7,890,"Serviço impecável",2024-01-14,Marie D.,septimeparis.com,"Custom, Shopify"
Você pode então: - Identificar os restaurantes bem avaliados (4.5+) com 500+ avaliações (tamanho significativo) - Ler as avaliações negativas para identificar os pontos fracos dos concorrentes - Ver quais restaurantes usam Shopify (vendendo online) vs WordPress (site customizado)
Caso 3: Prospecção ABM — Encontrar 500 restaurantes com site sem Google Analytics
Necessidade: restaurantes de médio porte (50-200 avaliações), nota 3.5+, site sem Google Analytics (lead potencial para agência de SEO/analytics).
Solução: Ferramenta dedicada com filtros avançados e detecção de tecnologias.
```javascript // Pseudo-código (a API do Google Maps não pode fazer isso) const restaurants = await tool.search({ location: 'França', category: 'restaurant', minRating: 3.5, minReviews: 50, maxReviews: 200, hasWebsite: true, missingTechnology: 'Google Analytics' // EXCLUSIVO });
// Resultado: 500 restaurantes qualificados // Você os contata com: "Vimos que seu site não tem
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.