WEB_SCRAPER (SCRAPE) - Extração Automática de Dados Web
O que é este Node?
O WEB_SCRAPER (SCRAPE) é o node responsável por extrair dados automaticamente de websites utilizando técnicas inteligentes de web scraping. Ele navega pela estrutura HTML da página, identifica o conteúdo principal e extrai textos, links, imagens e metadados de forma automática.
Por que este Node existe?
Coletar dados de websites manualmente é demorado, repetitivo e propenso a erros. O WEB_SCRAPER (SCRAPE) existe para:
- Automatizar coleta de dados: Extrai informações de sites de forma programática e escalável
- Integrar dados externos: Permite usar dados de sites externos em seus fluxos automatizados
- Monitorar conteúdo web: Coleta informações atualizadas de produtos, notícias, preços, etc.
- Enriquecer conversas: Busca dados em tempo real para responder perguntas dos usuários
- Respeitar limites éticos: Implementa delays, respeita robots.txt e evita sobrecarga de servidores
Como funciona internamente?
Quando o WEB_SCRAPER (SCRAPE) é executado, o sistema:
- Valida a URL: Verifica se a URL fornecida é válida e acessível
- Verifica robots.txt: Se configurado, consulta o robots.txt do site para verificar permissões
- Faz requisição HTTP: Busca o conteúdo HTML da página com headers personalizados
- Analisa HTML: Usa Cheerio para parsear o HTML e criar uma árvore DOM navegável
- Remove elementos indesejados: Elimina scripts, estilos, menus, rodapés conforme configurado
- Extrai conteúdo principal: Identifica automaticamente a área de conteúdo principal da página
- Coleta dados adicionais: Extrai links, imagens, metadados conforme solicitado
- Limpa e formata: Normaliza espaços em branco, remove linhas vazias e formata o texto
- Aplica rate limiting: Aguarda delay configurado antes da próxima requisição
- Retorna resultado: Devolve os dados extraídos no formato especificado
Código interno (web-scraper-executor.service.ts:95-197):
async execute(data: WebScraperNodeData, context: ExecutionContext): Promise<ExecutionResult> {
const startTime = Date.now();
this.logger.log(`Executing Web Scraper node ${context.nodeId} for URL(s): ${data.url || data.urls?.join(', ')}`);
try {
// Validate configuration
const validation = await this.validate(data);
if (!validation.isValid) {
return {
success: false,
error: `Validation failed: ${validation.errors?.join(', ')}`,
executionTime: Date.now() - startTime
};
}
// Determine target URLs
const urls = data.urls || (data.url ? [data.url] : []);
if (urls.length === 0) {
return {
success: false,
error: 'No URLs provided for scraping',
executionTime: Date.now() - startTime
};
}
// Check robots.txt if requested
if (data.respectRobots) {
for (const url of urls) {
const robotsCheck = await this.checkRobotsTxt(url, data.userAgent || 'LuminaBot/1.0');
if (!robotsCheck.allowed) {
this.logger.warn(`Robots.txt disallows scraping for ${url}`);
if (!data.ignoreErrors) {
return {
success: false,
error: `Robots.txt disallows scraping for ${url}`,
executionTime: Date.now() - startTime
};
}
}
}
}
// Execute scraping
const results: ScrapingResult[] = [];
const maxPages = Math.min(data.maxPages || 1, 50);
const delay = Math.max(data.delay || 1000, 500);
for (const url of urls.slice(0, maxPages)) {
try {
const scrapingResult = await this.scrapeUrl(url, data);
results.push(scrapingResult);
// Rate limiting
if (urls.indexOf(url) < urls.length - 1) {
await this.sleep(delay);
}
} catch (error) {
this.logger.error(`Failed to scrape ${url}:`, error.message);
if (!data.ignoreErrors) {
return {
success: false,
error: `Failed to scrape ${url}: ${error.message}`,
executionTime: Date.now() - startTime
};
} else {
results.push({
url,
error: error.message,
timestamp: new Date().toISOString(),
processingTime: 0
});
}
}
}
// Process results based on output format
const processedData = this.formatResults(results, data);
const totalItems = results.reduce((sum, result) => sum + (result.text ? 1 : 0), 0);
this.logger.log(`Web scraping completed successfully for node ${context.nodeId}. Scraped ${results.length} pages, found ${totalItems} items`);
return {
success: true,
data: processedData,
executionTime: Date.now() - startTime,
logs: [
`Scraped ${results.length} URLs`,
`Total items found: ${totalItems}`,
`Processing time: ${Date.now() - startTime}ms`
]
};
} catch (error) {
this.logger.error(`Web scraper execution failed for node ${context.nodeId}:`, error.stack);
return {
success: false,
error: error.message || 'Unknown web scraping error',
executionTime: Date.now() - startTime
};
}
}
Quando você DEVE usar este Node?
Use WEB_SCRAPER (SCRAPE) sempre que precisar de extrair dados estruturados de websites:
Casos de uso
- Monitoramento de preços: "Extraia diariamente os preços dos produtos concorrentes e salve no banco de dados"
- Agregação de notícias: "Colete as últimas notícias sobre tecnologia de 5 portais diferentes"
- Pesquisa de mercado: "Extraia avaliações de produtos de sites de e-commerce para análise"
- Enriquecimento de dados: "Busque informações adicionais sobre empresas em seus sites oficiais"
- Validação de informações: "Verifique se um endereço de loja existe no Google Maps"
Quando NÃO usar WEB_SCRAPER
- Sites com API oficial: Use a integração direta da API ao invés de scraping
- Sites que bloqueiam scrapers: Use serviços profissionais de scraping como ScraperAPI
- Sites com CAPTCHA: O node não resolve CAPTCHAs automaticamente
- Conteúdo JavaScript pesado: Use ferramentas com browser real como Puppeteer/Playwright
Parâmetros Detalhados
url (string, obrigatório)
O que é: A URL completa do website que você deseja extrair dados. Deve incluir o protocolo (http:// ou https://).
Padrão: Nenhum (obrigatório)
Flow completo para testar:
{
"name": "Teste Web Scraper - URL Básica",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Extrair Notícia",
"parameters": {
"operation": "scrape",
"url": "https://www.bbc.com/news",
"mode": "auto",
"extractText": true,
"extractLinks": true
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Mostrar Resultado",
"parameters": {
"message": "Título: {{scraper_1.data.data[0].title}}\n\nConteúdo extraído com sucesso!\nTotal de links: {{scraper_1.data.data[0].links.length}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Importe o flow e execute. O sistema irá extrair o conteúdo da página da BBC News e mostrar o título e quantidade de links encontrados.
mode (string, opcional)
O que é: Define o modo de extração de dados. Pode ser "auto" (extração automática inteligente), "manual" (usando seletores CSS) ou "template" (usando templates pré-configurados para tipos específicos de sites).
Padrão: "auto"
Valores aceitos: "auto", "manual", "template"
Flow completo para testar:
{
"name": "Teste Web Scraper - Modo Auto",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Modo Auto",
"parameters": {
"operation": "scrape",
"url": "https://example.com/article",
"mode": "auto",
"extractText": true,
"extractMeta": true
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Resultado",
"parameters": {
"message": "Conteúdo extraído automaticamente:\n{{scraper_1.data.data[0].text}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: O modo "auto" identifica automaticamente a área principal de conteúdo da página sem precisar configurar seletores CSS.
extractText (boolean, opcional)
O que é: Define se o texto do conteúdo principal da página deve ser extraído. Quando true, o sistema tenta identificar automaticamente a área de conteúdo principal (artigo, post, produto) e extrai todo o texto relevante.
Padrão: true
Flow completo para testar:
{
"name": "Teste Web Scraper - Extrair Texto",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Extrair Artigo",
"parameters": {
"operation": "scrape",
"url": "https://en.wikipedia.org/wiki/Artificial_intelligence",
"mode": "auto",
"extractText": true,
"cleanText": true,
"minTextLength": 100
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Mostrar Texto",
"parameters": {
"message": "Primeiros 500 caracteres:\n{{scraper_1.data.data[0].text.substring(0, 500)}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Execute e veja o texto principal do artigo da Wikipedia sendo extraído e limpo automaticamente.
extractLinks (boolean, opcional)
O que é: Define se todos os links (tags ) da página devem ser extraídos. Útil para descobrir páginas relacionadas, navegação ou análise de estrutura do site.
Padrão: false
Flow completo para testar:
{
"name": "Teste Web Scraper - Extrair Links",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Coletar Links",
"parameters": {
"operation": "scrape",
"url": "https://news.ycombinator.com",
"mode": "auto",
"extractLinks": true,
"extractText": false
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Contar Links",
"parameters": {
"message": "Total de links encontrados: {{scraper_1.data.data[0].links.length}}\n\nPrimeiros 5 links:\n{{scraper_1.data.data[0].links.slice(0, 5).join('\n')}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Coleta todos os links do Hacker News e mostra os 5 primeiros.
extractImages (boolean, opcional)
O que é: Define se todas as URLs de imagens (tags ) devem ser extraídas. O sistema converte URLs relativas em absolutas automaticamente.
Padrão: false
Flow completo para testar:
{
"name": "Teste Web Scraper - Extrair Imagens",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Coletar Imagens",
"parameters": {
"operation": "scrape",
"url": "https://unsplash.com",
"mode": "auto",
"extractImages": true,
"extractText": false
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Mostrar Resultado",
"parameters": {
"message": "Total de imagens: {{scraper_1.data.data[0].images.length}}\n\nPrimeira imagem:\n{{scraper_1.data.data[0].images[0]}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Extrai todas as URLs de imagens da página.
extractMeta (boolean, opcional)
O que é: Extrai metadados da página incluindo meta tags, Open Graph, Twitter Cards, canonical URL, idioma e charset. Útil para SEO e análise de conteúdo.
Padrão: false
Flow completo para testar:
{
"name": "Teste Web Scraper - Metadados",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Extrair Metadata",
"parameters": {
"operation": "scrape",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"mode": "auto",
"extractMeta": true
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Mostrar Meta",
"parameters": {
"message": "Título OG: {{scraper_1.data.data[0].metadata['og:title']}}\nDescrição: {{scraper_1.data.data[0].metadata['og:description']}}\nIdioma: {{scraper_1.data.data[0].metadata.lang}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Extrai metadados Open Graph de um vídeo do YouTube.
delay (number, opcional)
O que é: Tempo de espera em milissegundos entre requisições ao mesmo domínio. Respeita o servidor e evita bloqueios por sobrecarga.
Padrão: 1000 (1 segundo)
Mínimo: 500 (500ms - aplicado automaticamente se você tentar usar menos)
Flow completo para testar:
{
"name": "Teste Web Scraper - Rate Limiting",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Múltiplas URLs",
"parameters": {
"operation": "scrape",
"urls": [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3"
],
"mode": "auto",
"delay": 2000,
"extractText": true
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Resultado",
"parameters": {
"message": "Páginas extraídas: {{scraper_1.data.totalPages}}\nTempo total: {{scraper_1.data.totalProcessingTime}}ms"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Extrai 3 páginas com 2 segundos de intervalo entre cada requisição.
respectRobots (boolean, opcional)
O que é: Quando true, consulta o arquivo robots.txt do site antes de fazer scraping e respeita as regras de User-agent. Prática ética recomendada.
Padrão: false
Flow completo para testar:
{
"name": "Teste Web Scraper - Robots.txt",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Scraping Ético",
"parameters": {
"operation": "scrape",
"url": "https://www.google.com",
"mode": "auto",
"respectRobots": true,
"userAgent": "LuminaBot/1.0",
"ignoreErrors": false
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Status",
"parameters": {
"message": "Scraping permitido: {{scraper_1.success}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Tenta fazer scraping respeitando robots.txt. Se bloqueado, retorna erro.
cleanText (boolean, opcional)
O que é: Aplica limpeza no texto extraído: normaliza espaços em branco, remove linhas vazias e aplica trim. Deixa o conteúdo mais legível.
Padrão: false
Flow completo para testar:
{
"name": "Teste Web Scraper - Limpeza de Texto",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Extrair e Limpar",
"parameters": {
"operation": "scrape",
"url": "https://example.com",
"mode": "auto",
"extractText": true,
"cleanText": true,
"normalizeWhitespace": true,
"removeEmptyLines": true
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Texto Limpo",
"parameters": {
"message": "Texto formatado:\n{{scraper_1.data.data[0].text}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Extrai texto e aplica limpeza automática, removendo espaços extras.
outputFormat (string, opcional)
O que é: Define o formato de saída dos dados extraídos. Pode ser JSON (estruturado), CSV (tabular), XML (estruturado), HTML (original) ou TEXT (apenas texto).
Padrão: "json"
Valores aceitos: "json", "csv", "xml", "html", "text"
Flow completo para testar:
{
"name": "Teste Web Scraper - Formato CSV",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Extrair como CSV",
"parameters": {
"operation": "scrape",
"url": "https://example.com",
"mode": "auto",
"extractText": true,
"outputFormat": "csv"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Dados CSV",
"parameters": {
"message": "Formato CSV:\n{{scraper_1.data}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Retorna os dados em formato CSV pronto para exportação.
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | Tipo de operação ("scrape") |
| url | string | Sim* | URL do website a extrair |
| urls | string[] | Sim* | Array de URLs (alternativa a url) |
| mode | string | Não | Modo de extração: "auto", "manual", "template" (padrão: "auto") |
| extractText | boolean | Não | Extrair texto principal (padrão: true) |
| extractLinks | boolean | Não | Extrair links da página (padrão: false) |
| extractImages | boolean | Não | Extrair URLs de imagens (padrão: false) |
| extractMeta | boolean | Não | Extrair metadados (padrão: false) |
| delay | number | Não | Delay entre requisições em ms (padrão: 1000, mín: 500) |
| timeout | number | Não | Timeout da requisição em ms (padrão: 30000) |
| userAgent | string | Não | User-Agent customizado (padrão: "LuminaBot/1.0") |
| headers | object | Não | Headers HTTP adicionais |
| respectRobots | boolean | Não | Respeitar robots.txt (padrão: false) |
| cleanText | boolean | Não | Limpar e formatar texto (padrão: false) |
| normalizeWhitespace | boolean | Não | Normalizar espaços em branco (padrão: true se cleanText) |
| removeEmptyLines | boolean | Não | Remover linhas vazias (padrão: true se cleanText) |
| minTextLength | number | Não | Tamanho mínimo do texto extraído |
| outputFormat | string | Não | Formato de saída: "json", "csv", "xml", "text" (padrão: "json") |
| ignoreErrors | boolean | Não | Continuar mesmo com erros (padrão: false) |
| maxPages | number | Não | Número máximo de páginas (padrão: 1, máx: 50) |
*Obrigatório fornecer url OU urls
Exemplo 1: Monitoramento de Preços de Produto
Objetivo: Extrair preço de produto de e-commerce e alertar se mudou
JSON para Importar
{
"name": "Monitor de Preço de Produto",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Extrair Produto",
"parameters": {
"operation": "scrape",
"url": "https://www.amazon.com.br/dp/B08N5WRWNW",
"mode": "template",
"template": "ecommerce",
"delay": 2000,
"respectRobots": true,
"userAgent": "LuminaBot/1.0 (Product Monitoring)"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Salvar Dados",
"parameters": {
"variableName": "produto_info",
"value": "{{scraper_1.data.data[0].text}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Enviar Alerta",
"parameters": {
"message": "Produto monitorado:\n{{produto_info}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "variable_1" },
{ "source": "variable_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Produto monitorado:
{
"title": "Echo Dot (4ª Geração)",
"price": "R$ 349,00",
"description": "Smart speaker com Alexa...",
"availability": "Em estoque",
"rating": "4.8 estrelas"
}
Exemplo 2: Agregação de Notícias
Objetivo: Coletar últimas notícias de múltiplos portais
JSON para Importar
{
"name": "Agregador de Notícias Tech",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Coletar Notícias",
"parameters": {
"operation": "scrape",
"urls": [
"https://www.tecmundo.com.br",
"https://canaltech.com.br",
"https://olhardigital.com.br"
],
"mode": "template",
"template": "news",
"delay": 3000,
"extractMeta": true,
"outputFormat": "json"
}
}
},
{
"id": "loop_1",
"type": "loop",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Processar Cada Site",
"parameters": {
"items": "{{scraper_1.data.data}}",
"itemVariable": "site_data"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Resumir Notícia",
"parameters": {
"message": "Site: {{site_data.url}}\nTítulo: {{site_data.title}}\nAutor: {{JSON.parse(site_data.text).author}}\nData: {{JSON.parse(site_data.text).date}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "loop_1" },
{ "source": "loop_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Site: https://www.tecmundo.com.br
Título: Nova IA da OpenAI supera GPT-4
Autor: João Silva
Data: 13/10/2025
Sistema: Site: https://canaltech.com.br
Título: Apple anuncia iPhone 16
Autor: Maria Santos
Data: 13/10/2025
Sistema: Site: https://olhardigital.com.br
Título: SpaceX completa 100º lançamento
Autor: Pedro Costa
Data: 13/10/2025
Exemplo 3: Extração de Dados de Contato
Objetivo: Extrair informações de contato de páginas "Sobre" de empresas
JSON para Importar
{
"name": "Extrator de Dados de Contato",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "URL da Empresa",
"parameters": {
"message": "Digite a URL da página 'Sobre' ou 'Contato' da empresa:",
"variableName": "company_url"
}
}
},
{
"id": "scraper_1",
"type": "web_scraper",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Extrair Dados",
"parameters": {
"operation": "scrape",
"url": "{{company_url}}",
"mode": "auto",
"extractText": true,
"extractLinks": true,
"extractMeta": true,
"cleanText": true,
"normalizeWhitespace": true
}
}
},
{
"id": "ai_1",
"type": "ai",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Extrair Contatos com IA",
"parameters": {
"prompt": "Extraia do seguinte texto: email, telefone, endereço, horário de atendimento. Retorne em formato JSON.\n\nTexto:\n{{scraper_1.data.data[0].text}}",
"model": "gpt-4",
"variableName": "contact_info"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Mostrar Contatos",
"parameters": {
"message": "Informações extraídas:\n{{contact_info}}\n\nMetadados do site:\nTítulo: {{scraper_1.data.data[0].title}}\nIdioma: {{scraper_1.data.data[0].metadata.lang}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "scraper_1" },
{ "source": "scraper_1", "target": "ai_1" },
{ "source": "ai_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Digite a URL da página 'Sobre' ou 'Contato' da empresa:
Usuário: https://example-company.com/contact
Sistema: Informações extraídas:
{
"email": "contato@example-company.com",
"telefone": "+55 11 1234-5678",
"endereço": "Av. Paulista, 1000 - São Paulo, SP",
"horário": "Segunda a Sexta, 9h às 18h"
}
Metadados do site:
Título: Contato - Example Company
Idioma: pt-BR
Resposta do Node
{
"success": true,
"data": {
"totalPages": 1,
"successfulPages": 1,
"errors": [],
"totalProcessingTime": 2456,
"data": [
{
"url": "https://example.com",
"title": "Example Domain",
"text": "This domain is for use in illustrative examples...",
"links": [
"https://www.iana.org/domains/example"
],
"images": [
"https://example.com/logo.png"
],
"metadata": {
"og:title": "Example Domain",
"description": "Example website",
"lang": "en",
"canonical": "https://example.com"
},
"timestamp": "2025-10-13T12:30:00.000Z",
"processingTime": 2456
}
]
},
"executionTime": 2458,
"logs": [
"Scraped 1 URLs",
"Total items found: 1",
"Processing time: 2458ms"
]
}
Boas Práticas
✅ SIM:
- Use
delayde pelo menos 1-2 segundos entre requisições - Ative
respectRobots: truepara scraping ético - Configure
userAgentidentificando seu bot - Use
cleanText: truepara melhor qualidade de dados - Ative
ignoreErrors: trueao processar múltiplas URLs - Combine com node AI para estruturar dados extraídos
- Use
extractMeta: truepara informações de SEO - Limite
maxPagespara evitar sobrecarga
❌ NÃO:
- Fazer scraping sem delays (causa bloqueios)
- Ignorar robots.txt de sites que o proíbem
- Usar para sites com APIs oficiais disponíveis
- Fazer scraping massivo sem considerar impacto no servidor
- Extrair dados pessoais sem consentimento (LGPD)
- Usar User-Agent falso de browsers reais
- Tentar burlar CAPTCHAs ou sistemas anti-bot
Dicas
💡 Dica 1: Combine Web Scraper com node SCHEDULE para criar monitores automáticos que checam preços, vagas de emprego ou notícias periodicamente.
💡 Dica 2: Use o template "ecommerce" para extrair automaticamente preço, título, descrição e avaliação de produtos sem configurar seletores CSS.
💡 Dica 3: Ative extractSchemaOrg: true para extrair dados estruturados (JSON-LD) que sites bem construídos incluem. Retorna informações já formatadas.
💡 Dica 4: Para sites complexos, use mode: "manual" com seletores CSS específicos. Inspecione o HTML no navegador (F12) para encontrar os seletores corretos.
💡 Dica 5: Ao processar múltiplas URLs, use ignoreErrors: true e verifique o array errors no resultado para saber quais URLs falharam.
💡 Dica 6: Combine com node CONDITION para criar alertas: "se o preço for menor que R$ 500, envie mensagem no WhatsApp".
💡 Dica 7: Use outputFormat: "csv" quando precisar exportar dados para Excel ou planilhas do Google Sheets.
Próximo Node
→ WEB_SCRAPER (EXTRACT) - Extração com seletores CSS customizados → WEB_SCRAPER (CRAWL) - Navegação automática por múltiplas páginas → AI - Processar dados extraídos com inteligência artificial → CONDITION - Criar regras baseadas nos dados extraídos