Como Construir um Pipeline Preciso de Extração de Leads no Google Maps com Python
A prospecção B2B de alta conversão depende diretamente da confiabilidade dos dados coletados. O Google Maps é uma das fontes abertas mais atualizadas para identificar empresas locais, prestadores de serviço e comércios. No entanto, tentar extrair essas informações por meio de scripts simples costuma gerar listas repletas de números desatualizados, campos incompletos e dados duplicados.
Além disso, a interface do Google Maps faz uso extensivo de renderização do lado do cliente (CSR) e rolagem infinita virtualizada, o que torna abordagens tradicionais baseadas em simples requisições HTTP (requests convencionais) ineficazes. Para contornar esse problema e obter dados verdadeiramente úteis, é necessário implementar um pipeline robusto com automação de navegador moderno e camadas de validação estrita.
O Desafio da Coleta: Dinamismo e Higienização
Ao coletar dados do Google Maps, dois gargalos técnicos surgem com frequência:
- Virtualização do DOM: O navegador renderiza apenas os itens visíveis na tela. Conforme o usuário ou script rola o painel de resultados, os nós anteriores do DOM são destruídos ou reciclados para poupar memória.
- Qualidade dos Atributos: Nem todas as empresas listadas possuem site oficial, horários padronizados ou telefones com o formato correto (especialmente no padrão E.164).
Para solucionar isso, a arquitetura deve separar a etapa de varredura (navegação e extração de identificadores únicos, como o place_id ou URL do card) da etapa de extração detalhada e validação.
Arquitetura de Coleta com Playwright e Pydantic
Como especialista em automação de dados e inteligência artificial, costumo dividir o fluxo em três camadas funcionais: Navegação Resiliente, Parsing Estruturado e Higienização de Dados.
Abaixo está um exemplo prático demonstrando a captura básica dos elementos e a validação estrutural dos dados utilizando playwright assíncrono e pydantic:
python
import asyncio
from pydantic import BaseModel, HttpUrl, fieldvalidator
import phonenumbers
from playwright.asyncapi import async_playwright
class LeadModel(BaseModel):
nome: str
telefone: str | None = None
site: HttpUrl | None = None
endereco: str | None = None
@field_validator('telefone')
@classmethod
def validar_telefone(cls, v):
if not v:
return None
try:
# Normaliza para padrão internacional (E.164)
parsed = phonenumbers.parse(v, "BR")
if phonenumbers.is_valid_number(parsed):
return phonenumbers.format_number(parsed, phonenumbers.PhoneNumberFormat.E164)
except Exception:
return None
return None
async def extrairdetalheslocal(page, urllocal: str) -> LeadModel:
await page.goto(urllocal, wait_until=”networkidle”)
# Extração pontual com seletores resilientes por acessibilidade ou classes parciais
nome = await page.locator('h1.DUwDvf').inner_text() if await page.locator('h1.DUwDvf').count() > 0 else "Desconhecido"
# Localização aproximada de dados de contato via seletores de ação
telefone = None
tel_locator = page.locator('button[data-tooltip*="Copiar número de telefone"], button[data-item-id*="phone"]')
if await tel_locator.count() > 0:
telefone = await tel_locator.first.inner_text()
site = None
site_locator = page.locator('a[data-item-id="authority"]')
if await site_locator.count() > 0:
site = await site_locator.first.get_attribute('href')
return LeadModel(nome=nome, telefone=telefone, site=site)
Estratégia em Três Fases para Listas Precisas
Para garantir que o conjunto de dados seja entregue limpo e utilizável por um time de vendas ou CRM, aplicamos o seguinte fluxo:
1. Descoberta e Scroll Estável
Em vez de coletar todos os atributos detalhados na lista de resultados, o script deve capturar apenas os links diretos para a página de cada estabelecimento. Isso mantém o scroll rápido e reduz a chance de timeouts causados pela re-renderização de painéis pesados.
2. Visita Individual e Extração Atômica
Com a lista de URLs exclusivas em mãos, o robô navega em abas assíncronas isoladas para cada empresa. Esse isolamento garante que falhas pontuais de conexão ou campos faltantes em um local não interrompam o processamento dos demais.
3. Validação e Enriquecimento Automático
Antes de persistir os dados em um banco ou arquivo estruturado (CSV/Parquet), a camada de validação aplica regras de higienização:
- Remoção de DDDs inconsistentes ou linhas com números corporativos genéricos.
- Teste de resolução DNS nos domínios encontrados para assegurar que os sites continuam no ar.
- Desduplicação cruzada via coordenadas geográficas ou nome canônico normalizado.
Conclusão e Próximos Passos
Construir um coletor preciso de dados comerciais vai além de automatizar cliques; trata-se de garantir integridade matemática e semântica aos registros entregues ao pipeline de vendas. Ferramentas genéricas muitas vezes geram custos ocultos ao entregar contatos inválidos ou leads desatualizados.
Se a sua empresa precisa de uma solução proprietária de inteligência de mercado, pipelines customizados de extração e validação de dados em larga escala, agende uma consultoria técnica no blog Thiago Programador para avaliarmos a melhor arquitetura para o seu negócio.


