🎯 Um navegador em nuvem personalizável e anti-detecção alimentado por Chromium desenvolvido internamente, projetado para rastreadores web e agentes de IA. 👉Experimente agora
De volta ao blog

Como Construir um Scraper do Google Maps com Scrapeless Browserless: O Guia Definitivo Pronto para IA para 2026

Ethan Brown
Ethan Brown

Advanced Bot Mitigation Engineer

15-Apr-2026

Principais Conclusões:

  • Google Maps é uma fonte de dados incomparável para geração de leads B2B, SEO local e inteligência de mercado, mas suas defesas são sofisticadas.
  • Scrapeless Scraping Browser atua como uma poderosa infraestrutura de navegador AI, oferecendo resolução automatizada de CAPTCHA, impressão digital anti-detecção e proxies residenciais para contornar as formidáveis medidas anti-bot do Google.
  • Geo-grid tiling é a técnica essencial para superar o limite inerente de busca de 120 lugares, permitindo a extração de milhares de listagens de negócios únicas de uma área específica.
  • A plataforma Scrapeless Scraping Browser fornece saída estruturada em JSON/HTML/Markdown pronta para agente AI, integrando-se perfeitamente em fluxos de trabalho e pipelines de dados avançados de AI.
  • Dominar as nuances da renderização dinâmica do Google Maps e implementar uma lógica de nova tentativa robusta são cruciais para construir uma solução de navegador de scraping escalável que funcione de forma confiável em escala de produção.

Introdução: Desbloqueando a Mina de Ouro do Google Maps na Era da AI

Com base em ampla experiência prática com crawlers da web, podemos perceber que há um padrão consistente toda vez que você constrói um do zero. A primeira hora parece ótima. Na segunda hora você encontra a primeira barreira. Ao final do dia, você percebe que escreveu trezentas linhas de código apenas para extrair um título de forma confiável.

O Google Maps é o conjunto de dados de negócios públicos mais rico da web. Cada listagem tem um nome, telefone, site, endereço, categoria, classificação, contagem de avaliações, horários de funcionamento, GPS, fotos, atributos de serviço e um fluxo ao vivo de avaliações. E o Google não quer que você tenha isso em massa. A API Places cobra por solicitação, limita severamente e deixa de fora campos que a interface da web regular mostra livremente. Portanto, quem realmente precisa desses dados em grande escala acaba raspando.

Este guia passa por um scraper TypeScript de arquivo único em cima do Scrapeless Scraping Browser que lida com as partes que normalmente consomem semanas: anti-detecção, proxies residenciais, CAPTCHA, o limite de 120 lugares e a forma como o Google Maps apresenta um painel reduzido ao abrir uma URL de lugar diretamente. Um arquivo, uma execução, todos os campos.


O Que Você Pode Fazer Com Isso

Os dados do Google Maps são um ativo versátil, gerando aplicações comerciais de alto impacto, desde geração de leads até análises avançadas de AI.

O valor derivado dos dados do Google Maps se estende muito além de listas de contato simples. Sua natureza estruturada e atualizações em tempo real fazem dele um recurso indispensável para diversas aplicações comerciais. Aqui estão cinco usos comerciais do mundo real, todos alcançáveis a partir do mesmo código-base, muitas vezes com apenas uma mudança na configuração:

  1. Geração de leads B2B. Execute o scraper sobre "encanadores" em Phoenix ou "dentistas" em Chicago, defina maxPlaces: 500 com uma grade 3×3, e você sairá com um CSV de nome, telefone, site, endereço, categoria e avaliação para cada negócio na área. Envie isso para seu CRM ou uma ferramenta de e-mail outbound. Esta é a razão mais comum pela qual as pessoas raspam o Google Maps e a mais fácil de monetizar.
  2. Monitoramento de avaliações e reputação. Programe uma execução diária para sua própria empresa mais três a cinco concorrentes, armazene o JSON com um carimbo de data/hora e faça diff em reviews[] por publishedAtDate entre snapshots. Nova avaliação de 1 estrela em um concorrente? Alerta no Slack. Nova de 5 estrelas na sua? Envie para seu site de marketing. O texto completo da avaliação está na saída — autor, estrelas, data, resposta do proprietário, tudo.
  3. Inteligência imobiliária e de localização. Divida um bairro em um raio de célula de 500m, extraia cada cafeteria, academia e mercado, e depois plote a densidade em um mapa. Investidores imobiliários usam isso para comparar a cobertura de comodidades entre endereços candidatos; cadeias de varejo usam para seleção de locais. O campo location.{lat,lng} em cada lugar torna isso uma única linha de groupby.
  4. Rastreamento de classificação SEO local. O scraper registra a classificação por lugar por célula. Divida uma cidade em células de 1 km, extraia "encanador" de cada uma, veja onde seu negócio cliente se classifica na grade. O mapa de classificação por célula É o mapa de calor de SEO local que a Whitespark e a BrightLocal vendem como um produto. Construa você mesmo em cinquenta linhas de código em cima da saída JSON.
  5. Conjuntos de dados de ML e análises. Execute o scraper em quarenta consultas × vinte cidades e você terá um conjunto de dados de dezenas de milhares de negócios com atributos estruturados, horários de funcionamento e texto de avaliações. Alimente reviews[].text em um classificador de sentimentos, treine um recomendador em categories × additionalInfo, ou apenas use como um corpus de referência.

Por Que Scrapeless

Executar um navegador headless no seu próprio laptop funciona por cerca de dez minutos. Depois disso, o Google detecta a impressão digital do TLS, a saída do WebGL, os padrões de tempo, e você começa a ver portões de consentimento, CAPTCHAs e avisos de "tráfego incomum". Você pode combater isso com plugins stealth por um tempo, mas é um jogo perdido.

Scrapeless Scraping Browser é um navegador em nuvem que realmente se parece com um navegador real para o Google. Ele vem com:

  • Fingerprinting anti-deteção que se mantém sob carga real
  • Proxies residenciais em mais de 195 países
  • Solução automática de CAPTCHA
  • Gravação de sessão para depuração
  • Endpoints WebSocket que suportam frameworks baseados em CDP como Puppeteer e Playwright, então não há SDK para aprender

Você se conecta com frameworks baseados em CDP que normalmente usaria, apenas contra uma URL diferente. Todo o resto é puro Puppeteer.

Obtenha sua chave de API para o plano gratuito em app.scrapeless.com).


Pré-requisitos

  • Node 18 ou mais recente.
  • Uma chave Scrapeless (o nível gratuito é aceitável).
  • Alguma familiaridade com Puppeteer ajuda, mas não é obrigatória.
  • Sem Chrome local. O navegador é executado na nuvem.

Instalação

bash Copy
mkdir google-maps-pro && cd google-maps-pro
npm init -y
npm install puppeteer-core dotenv
npm install -D tsx typescript @types/node

E um .env:

env Copy
SCRAPELESS_API_KEY=your_key_here

Passo 1 — Conectar

Cada sessão é aberta da mesma forma. Construa uma URL WSS com seu token, país e TTL, e depois entregue-a a puppeteer.connect.

typescript Copy
import "dotenv/config";
import puppeteer from "puppeteer-core";

function connectionURL(sessionName: string, proxyCountry = "US", sessionTTL = 600) {
  const qs = new URLSearchParams({
    token: process.env.SCRAPELESS_API_KEY!,
    proxyCountry,
    sessionTTL: String(sessionTTL),
    sessionName,
  });
  return `wss://browser.scrapeless.com/api/v2/browser?${qs.toString()}`;
}

async function openBrowser(sessionName: string) {
  return puppeteer.connect({
    browserWSEndpoint: connectionURL(sessionName),
    defaultViewport: null,
  });
}

Essa é toda a área de superfície específica do Scrapeless. Tudo o que vem depois é Puppeteer normal. O modelo no repositório passa essas opções como um único objeto cfg em vez de argumentos posicional — mesmo efeito, apenas mais limpo uma vez que você tenha uma dúzia de ajustes.


Passo 2 — O limite de 120 lugares

Abra o Google Maps em um navegador e procure por "restaurantes em Nova York". Role o quanto quiser. Você nunca verá mais de cerca de 120 resultados. A interface simplesmente para de fornecer mais.

Essa é a coisa mais frustrante sobre raspar o Google Maps, e muitos projetos de primeira viagem simplesmente convivem silenciosamente com isso. Você não pode rolar para isso. Você não pode paginar além disso. O limite está embutido na interface.

A solução alternativa é o tijolamento de grid geográfico. Divida a área alvo em uma grade de células menores, execute uma pesquisa por célula com um centro de coordenadas diferente, mescle os resultados e elimine duplicatas por placeId. Uma grade 2×2 sobre o centro de Austin transforma uma pesquisa em quatro e consegue cerca de 400 lugares únicos em vez de 120. Uma 3×3 facilmente ultrapassa mil.

A matemática da grade é simples o suficiente:

typescript Copy
function kmPerDegLng(lat: number) { return 111.32 * Math.cos((lat * Math.PI) / 180); }
function kmPerDegLat() { return 111.32; }

function buildGrid(centerLat: number, centerLng: number, cellRadiusKm: number, maxCells: number) {
  const side = Math.max(1, Math.floor(Math.sqrt(maxCells)));
  const cells: { lat: number; lng: number }[] = [];
  const stepLat = (cellRadiusKm * 2) / kmPerDegLat();
  const stepLng = (cellRadiusKm * 2) / kmPerDegLng(centerLat);
  const offset = (side - 1) / 2;
  for (let i = 0; i < side; i++) {
    for (let j = 0; j < side; j++) {
      cells.push({
        lat: centerLat + (i - offset) * stepLat,
        lng: centerLng + (j - offset) * stepLng,
      });
      if (cells.length >= maxCells) return cells;
    }
  }
  return cells;
}

function searchUrlForCell(query: string, lat: number, lng: number) {
  const q = encodeURIComponent(query).replace(/%20/g, "+");
  return `https://www.google.com/maps/search/${q}/@${lat.toFixed(6)},${lng.toFixed(6)},15z`;
}

O fragmento @lat,lng,15z na URL é o que recentra o mapa para cada busca. O 15z é um nível de zoom. Aumente para células mais apertadas, diminua para células mais amplas.


Passo 3 — Raspar o feed de resultados

Para cada URL de célula, role a barra lateral de resultados até parar de carregar novos cartões, depois pegue todos os links a.hfpxzc.

typescript Copy
async function collectSearchResults(page: Page, searchUrl: string, target: number) {
  await page.goto(searchUrl, { waitUntil: "domcontentloaded", timeout: 60000 });
  await page.waitForSelector('div[role="feed"], h1.DUwDvf', { timeout: 25000 });

  let last = 0, stable = 0;
  for (let i = 0; i < 40; i++) {
    const n = await page.$$eval(".Nv2PK", (els) => els.length);
    if (n >= target) break;

Se (n === last) { estável++; se (estável >= 3) break; } senão estável = 0;
último = n;
await page.evaluate(() => {
const feed = document.querySelector('div[role="feed"]');
if (feed) (feed as HTMLElement).scrollTop = (feed as HTMLElement).scrollHeight;
});
await new Promise(r => setTimeout(r, 1500));
}

return page.$$eval(".Nv2PK a.hfpxzc", (links) =>
links.map((el, idx) => ({
nome: el.getAttribute("aria-label") || "",
url: (el as HTMLAnchorElement).href,
rank: idx + 1,
})),
);
}

Copy
O **padrão de contador estável** (três rolagens sem novos resultados significam que o feed acabou) supera um sono fixo toda vez. Esperar mais não ajuda se o feed realmente parou de carregar.

O `placeId` está embutido em cada URL, após `!1s0x...:0x....` Essa é a chave de desduplicação entre células.

---

## Passo 4 — A Coisa Estranha de Renderização do Google Maps

Isso me custou a maior parte de um dia para descobrir.

Se você navegar diretamente para uma URL de lugar como `https://www.google.com/maps/place/Haraz+Coffee+House/...`, o Google Maps renderiza uma versão simplificada do painel. O título `h1` está lá. A classificação está lá. Mas a contagem de avaliações, a tabela de horários de abertura, os atributos de serviço, as fotos — metade disso está faltando ou tem conteúdo de texto vazio. Todo o DOM da página chega a cerca de três mil caracteres.

Se você navegar até os resultados de pesquisa e clicar no mesmo card do lugar, você obtém o painel rico completo. Mesma URL, renderização completamente diferente.

A solução é: **sempre passe pela URL de pesquisa, clique no card do lugar que você quer e aguarde o painel.**

```typescript
const clicked = await page.evaluate((placeName) => {
  const cards = document.querySelectorAll(".Nv2PK a.hfpxzc");
  for (const c of Array.from(cards)) {
    if (c.getAttribute("aria-label") === placeName) {
      (c as HTMLElement).click();
      return true;
    }
  }
  return false;
}, hit.name);

await page.waitForSelector("h1.DUwDvf", { timeout: 15000 });

Uma rápida verificação de sanidade após o seletor aparecer: verifique o h1 para conteúdo de texto não vazio antes de prosseguir. Às vezes, o elemento aparece antes que o Google realmente o preencha.


Passo 5 — Puxe a Visão Geral

Uma vez que você esteja em um painel rico real, um page.evaluate captura a maioria dos campos básicos.

typescript Copy
const overview = await page.evaluate(() => {
  const $ = (s: string) => document.querySelector(s) as HTMLElement | null;
  const txt = (s: string) => $(s)?.textContent?.trim() || null;

  return {
    título: txt("h1.DUwDvf"),
    pontuaçãoTotal: parseFloat(txt('div.F7nice span[aria-hidden="true"]') || "") || null,
    nomeCategoria: txt("button.DkEaL"),
    endereço: txt('button[data-item-id="address"] .Io6YTe'),
    telefone: txt('button[data-item-id*="phone"] .Io6YTe'),
    site: txt('a[data-item-id="authority"] .Io6YTe'),
    plusCode: txt('button[data-item-id="oloc"] .Io6YTe'),
  };
});

Lat, lng e o hash do placeId estão todos na URL, não no DOM:

typescript Copy
const at = page.url().match(/@(-?\d+\.\d+),(-?\d+\.\d+)/);
const location = at ? { lat: parseFloat(at[1]), lng: parseFloat(at[2]) } : null;
const placeId = page.url().match(/!1s(0x[0-9a-f]+:0x[0-9a-f]+)/i)?.[1] ?? null;

Um aviso sobre os nomes das classes. DUwDvf, F7nice, Io6YTe, todos esses são gerados automaticamente pela construção do Google e eles realmente mudam. Verifique sua saída contra um lugar conhecido a cada uma ou duas semanas e esteja preparado para atualizar os seletores quando algo cair para nulo.


O painel do lugar tem abas. Você clica em cada, espera, rola, extrai. A ordem importa aqui, o que não é óbvio até você ter enfrentado o problema uma vez.

Faça Sobre / atributos primeiro. O conteúdo Sobre vive dentro do painel de Visão Geral. Se você clicar em Avaliações ou Fotos antes de puxar os atributos, esses nós serão desmontados e você os perderá.

Avaliações. Clique na aba, escolha uma ordem de classificação se importar (mais recente, mais alta, mais baixa ou relevante), em seguida, role o painel até ter tantas cartas carregadas quanto deseja. Cada carta tem o nome do autor, texto, estrelas, uma data relativa, a foto do revisor e, às vezes, uma resposta do proprietário.

typescript Copy
const reviews = await page.evaluate((max) => {
  const cards = Array.from(document.querySelectorAll(".Nv2PK"));
  return cards.slice(0, max).map((c) => ({
    nome: c.querySelector(".d4r55")?.textContent?.trim() || null,
    texto: c.querySelector(".wiI7pd")?.textContent?.trim() || null,
    dataPublicada: c.querySelector(".rsqaWe")?.textContent?.trim() || null,
    estrelas: (() => {
      const m = (c.querySelector(".kvMYJc")?.getAttribute("aria-label") || "").match(/(\d)/);
      return m ? parseInt(m[1], 10) : null;
    })(),
    respostaDoProprietárioTexto: c.querySelector(".CDe7pd .wiI7pd")?.textContent?.trim() || null,
  }));
}, 30);

Um detalhe: corpos de avaliações mais longos são truncados com um botão "Mais". Clique em todos esses antes de extrair ou você acabará com avaliações incompletas.
Fotos: Role a galeria e pegue cada URL de background-image CSS. O URL termina em algo como =w150-h150 para a miniatura; troque isso para =w1600-h1600 para o tamanho completo. Mesmo URL, sufixo de tamanho diferente.
Cardápio, Perguntas e Respostas: Cada um é um clique na guia com seu próprio conjunto de seletores. Nem todo lugar possui isso. Cafeterias, por exemplo, geralmente não exibem um cardápio no Google Maps.


Passo 7 — Fazendo Funcionar em Escala

Essa é a parte que separa um script que meio que funciona de um que você pode deixar rodando durante a noite.

O Google Maps é instável. O estado da SPA fica estranho após cliques nas guias. Um clique às vezes funciona, mas a guia nunca se popula. O feed ocasionalmente carrega com zero resultados sem motivo óbvio e um recarregamento resolve. Se você está atingindo um ou dois lugares manualmente, isso é apenas um pequeno incômodo, mas em um volume real, eles se acumulam rapidamente.

Duas coisas resolvem isso:

  1. Navegador novo por lugar. Depois de coletar os resultados da pesquisa, abra uma nova sessão do Scraping Browser para cada lugar. Reutilizar uma sessão entre lugares pode parecer uma otimização óbvia, mas o estado do painel do lugar N vaza para o lugar N+1 de maneiras que são genuinamente difíceis de depurar. Nova sessão toda vez, e o problema simplesmente desaparece.
  2. Tente até três vezes. Quase todas as falhas são transitórias.
typescript Copy
for (let attempt = 1; attempt <= 3; attempt++) {
  const eb = await openBrowser(`gmp-enrich-${attempt}`);
  const ep = await eb.newPage();
  try {
    await ep.goto(searchUrl, { waitUntil: "domcontentloaded", timeout: 60000 });
    await ep.waitForSelector('div[role="feed"]', { timeout: 20000 });
    const place = await enrichPlaceOnSearchPage(ep, hit, cfg);
    if (place.title) return place;
  } finally {
    await ep.close();
    await eb.close();
  }
  await new Promise(r => setTimeout(r, 2000));
}

Durante os testes que fiz enquanto construía isso — cafeterias em Austin, restaurantes em Manhattan, dentistas em Chicago — a taxa de sucesso por lugar foi em torno de 75–100%. As falhas são quase sempre o Google não renderizando o painel após um clique no cartão, e o loop de tentativas captura a maioria delas.


O Que Você Receberá

Um objeto JSON simples por lugar. É deliberadamente amplo, para que você não precise executar o scraper uma segunda vez para obter uma fatia diferente — geração de leads, avaliações, atributos, tudo em um único payload.

Aqui está um resultado real de uma execução recente no Haraz Coffee House em Austin:

json Copy
{
  "title": "Haraz Coffee House",
  "placeId": "0x8644b52f8462f95f:0xa572bbcb1887b9bb",
  "cid": "11921797644567427515",
  "url": "https://www.google.com/maps/place/Haraz+Coffee+House/...",
  "rank": 2,
  "address": "500 W Martin Luther King Jr Blvd Suite A, Austin, TX 78701",
  "plusCode": "77J4+WJ Austin, Texas",
  "location": { "lat": 30.2823385, "lng": -97.7434096 },
  "phone": "(512) 243-5667",
  "phoneUnformatted": "5122435667",
  "website": "harazcoffeehouse.com",
  "domain": "harazcoffeehouse.com",
  "categoryName": "Cafeteria",
  "categories": ["Cafeteria"],
  "totalScore": 4.7,
  "reviewsCount": 47239,
  "openingHours": [
    { "day": "Segunda-feira", "hours": "7 AM–10 PM" },
    { "day": "Terça-feira", "hours": "7 AM–10 PM" },
    "... 5 dias a mais"
  ],
  "additionalInfo": {
    "Opções de serviço": [
      { "name": "No local", "value": true },
      { "name": "Para viagem", "value": true }
    ],
    "Acessibilidade": [
      { "name": "Entrada acessível para cadeirantes", "value": true }
    ],
    "Destaques": [{ "name": "Ótimo café", "value": true }],
    "... 10 seções a mais": {}
  },
  "images": [
    "https://lh3.googleusercontent.com/.../=w1600-h1600",
    "... 4 URLs a mais"
  ],
  "reviews": [
    {
      "name": "Maria T",
      "text": "Melhor latte em Austin, sem dúvida...",
      "publishedAtDate": "há 14 horas",
      "stars": 5,
      "reviewerPhotoUrl": "https://lh3.googleusercontent.com/...",
      "responseFromOwnerText": "Obrigado, Maria!"
    },
    "... 9 avaliações a mais"
  ],
  "menu": [],
  "questionsAndAnswers": [],
  "popularTimesLiveText": null,
  "scrapedAt": "2026-04-13T13:23:18.450Z"
}

O que você receberá — Cada execução retorna JSON estruturado com esses campos: título, placeId, cid, endereço, plusCode, localização.{lat,lng}, telefone, telefone não formatado, website, domínio, categoryName, categorias, preço, totalScore, reviewsCount, openingHours[], additionalInfo{}, images[], reviews[], questionsAndAnswers[], menu[], popularTimesLiveText, plus flags de status. Arrays vazios / nulo para campos que o Google não exibe para esse tipo de lugar.


Conclusão: Potencializando Seus Agentes de IA com Dados do Mundo Real

Dominar a extração do Google Maps com Scrapeless Scraping Browser é o caminho definitivo para construir agentes de IA autônomos que realmente entendem e interagem com o mundo físico.
A jornada para extrair dados valiosos do Google Maps está repleta de desafios técnicos, desde o limite de 120 locais até sofisticadas defesas contra bots. No entanto, ao aproveitar as capacidades avançadas do Scrapeless Scraping Browser—sua infraestrutura de navegador AI dedicada—você pode transformar esses obstáculos em oportunidades. Este guia equipou você com uma solução robusta, pronta para AI, que combina o mapeamento em grade geográfica, extração inteligente de dados e melhores práticas de nível de produção.

Se seu objetivo é gerar leads B2B de alta qualidade, monitorar o desempenho de SEO local, conduzir pesquisas de mercado aprofundadas ou alimentar seus agentes de IA com inteligência estruturada e em tempo real sobre o mundo físico, o Scrapeless fornece a base confiável que você precisa. Pare de lutar contra as medidas anti-bot e comece a focar no que realmente importa: as percepções derivadas dos seus dados.

Pronto para Construir Seu Pipeline de Dados Com IA?

Junte-se à nossa comunidade vibrante para reivindicar um plano gratuito e conectar-se com outros inovadores:


FAQ

Q: Preciso de um proxy para extrair do Google Map?
A: Sim. Sem um, você começará a ser limitado em taxa dentro de algumas solicitações, e daí em diante serão 429s e paredes de consentimento. O Scrapeless Scraping Browser tem proxies residenciais integrados, então não há nada separado para integrar. Cada sessão que você abre passa por um IP residencial diferente no país que você escolher.

Q: Quantos locais posso realmente extrair?
A: Depende da cidade. Uma grade 2×2 de células de 2 km sobre um centro urbano de médio porte nos EUA oferece 200–400 locais únicos após a deduplicação. Aumente para uma grade 3×3 ou 4×4 em metrôs densos e você pode facilmente chegar aos milhares.

Q: O que acontece quando o Google muda os nomes das classes?
A: Isso acontece a cada poucos meses. O scraper usa múltiplos seletores de fallback por campo, então geralmente apenas um campo quebra por vez enquanto os outros continuam funcionando. Fique de olho nos seus logs, atualize os seletores quando algo cair para nulo, e siga em frente.

Q: Por que usar o Scrapeless Scraping Browser em vez de um navegador headless local?
A: O Scrapeless Scraping Browser oferece detecção contra bot de nível empresarial, resolução automatizada de CAPTCHAs e proxies residenciais integrados—recursos que são extremamente difíceis e custosos de implementar e manter com uma configuração de navegador headless local. Ele fornece uma verdadeira infraestrutura de navegador AI, permitindo que você se concentre na lógica de extração de dados em vez de lutar contra medidas anti-bot.

Q: E quanto ao reviewsCount?
A: O scraper lê reviewsCount do bloco F7nice na aba de Visão Geral — o número entre parênteses que aparece logo após a avaliação ("4.7 (1.234)"). Quando o Google renderiza a contagem, ela é precisa. Para qualquer local onde o scraper extraiu com sucesso os cartões de revisão, reviews.length também é uma contagem confiável.

Na Scorretless, acessamos apenas dados disponíveis ao público, enquanto cumprem estritamente as leis, regulamentos e políticas de privacidade do site aplicáveis. O conteúdo deste blog é apenas para fins de demonstração e não envolve atividades ilegais ou infratoras. Não temos garantias e negamos toda a responsabilidade pelo uso de informações deste blog ou links de terceiros. Antes de se envolver em qualquer atividade de raspagem, consulte seu consultor jurídico e revise os termos de serviço do site de destino ou obtenha as permissões necessárias.

Artigos mais populares

Catálogo