Web Scraper Service

Um servidor MCP baseado em Python para raspagem web headless. Ele extrai o conteúdo principal de texto de páginas da web e o gera como Markdown, texto ou HTML.

Documentação

Web Scraper Service (MCP Stdin/Stdout & HTTP)

Build Test Version License Python PEP8 GHCR Patchright Docker

Um servidor MCP baseado em Python para raspagem web robusta e headless—extrai o conteúdo principal de texto de páginas web e gera Markdown, texto ou HTML para integração perfeita com IA e automação.

Principais Recursos

  • Raspagem com navegador headless (Playwright, BeautifulSoup, Markdownify)
  • Gera Markdown, texto ou HTML
  • Projetado para integração com MCP (Model Context Protocol) stdio/JSON-RPC
  • Transporte duplo: stdio (padrão) e HTTP Streamable para modo de serviço compartilhado
  • Pool de navegadores persistente: Chromium permanece ativo entre requisições para raspagem rápida
  • Espera inteligente de DOM: estabilização de conteúdo baseada em MutationObserver em vez de espera fixa
  • Dockerizado, com imagens pré-construídas
  • Configurável via variáveis de ambiente
  • Tratamento robusto de erros (timeouts, erros HTTP, Cloudflare, etc.)
  • Limitação de taxa por domínio
  • Integração fácil com ferramentas de IA e IDEs (Cursor, Claude Desktop, Continue, JetBrains, Zed, etc.)
  • Instalação com um clique para Cursor, instalador interativo para Claude

Início Rápido

Executar com Docker (modo stdio — um contêiner por cliente)

docker run -i --rm ghcr.io/justazul/web-scrapper-stdio

Executar como Serviço HTTP Compartilhado (um contêiner, múltiplos clientes)

docker run -d --name web-scraper \
  -e MCP_TRANSPORT=streamable-http \
  -e MCP_HTTP_PORT=8080 \
  -e BROWSER_POOL_SIZE=3 \
  -p 8080:8080 \
  --shm-size=3gb \
  ghcr.io/justazul/web-scrapper-stdio

Ou com Docker Compose:

docker compose --profile service up -d

Instalação com Um Clique (IDE Cursor)

Add to Cursor


Modos de Transporte

stdio (padrão)

Cada cliente MCP inicia seu próprio contêiner via docker run -i. Simples, zero configuração, funciona com qualquer cliente MCP.

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/justazul/web-scrapper-stdio"]
    }
  }
}

HTTP Streamable (serviço compartilhado)

Execute um contêiner persistente que atende múltiplos clientes MCP via HTTP. Economiza recursos ao executar múltiplas instâncias de ferramentas de IA (por exemplo, múltiplas sessões do Claude Code).

Inicie o serviço:

docker run -d --name web-scraper \
  -e MCP_TRANSPORT=streamable-http \
  -e MCP_HTTP_PORT=8080 \
  -p 8080:8080 \
  --shm-size=3gb \
  ghcr.io/justazul/web-scrapper-stdio

Conecte-se a partir do seu cliente MCP:

{
  "mcpServers": {
    "web-scrapper": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Integração com Ferramentas de IA e IDEs

Este serviço suporta integração com uma ampla gama de ferramentas de IA e IDEs que implementam o Model Context Protocol (MCP). Abaixo estão exemplos de configuração prontos para uso nos ambientes mais populares. Substitua a imagem/tag conforme necessário para builds personalizados.

IDE Cursor

Adicione ao seu .cursor/mcp.json (nível de projeto) ou ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/justazul/web-scrapper-stdio"
      ]
    }
  }
}

Claude Desktop

Adicione à configuração MCP do Claude Desktop (tipicamente claude_desktop_config.json):

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/justazul/web-scrapper-stdio"
      ]
    }
  }
}

Claude Code

Adicione ao seu .mcp.json ou ~/.claude.json global:

Modo stdio (um contêiner por sessão):

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/justazul/web-scrapper-stdio"]
    }
  }
}

Modo HTTP (serviço compartilhado — inicie o serviço primeiro):

{
  "mcpServers": {
    "web-scrapper": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Continue (Plugin VSCode/JetBrains)

Adicione ao seu continue.config.json ou via configurações MCP do plugin Continue:

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/justazul/web-scrapper-stdio"
      ]
    }
  }
}

IntelliJ IDEA (JetBrains AI Assistant)

Vá para Settings > Tools > AI Assistant > Model Context Protocol (MCP) e adicione um novo servidor. Use:

{
  "command": "docker",
  "args": [
    "run",
    "-i",
    "--rm",
    "ghcr.io/justazul/web-scrapper-stdio"
  ]
}

Editor Zed

Adicione à configuração MCP do Zed (consulte a documentação do Zed para o caminho exato):

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/justazul/web-scrapper-stdio"
      ]
    }
  }
}

Uso

Servidor MCP (Ferramenta/Prompt)

Este raspador web é usado como uma ferramenta MCP (Model Context Protocol), permitindo que seja usado por modelos de IA ou outra automação diretamente.

Ferramenta: scrape_web

Parâmetros:

  • url (string, obrigatório): A URL a ser raspada
  • max_length (inteiro, opcional): Comprimento máximo do conteúdo retornado (padrão: ilimitado)
  • timeout_seconds (inteiro, opcional): Timeout em segundos para o carregamento da página (padrão: 30)
  • user_agent (string, opcional): String de User-Agent personalizada passada diretamente ao navegador (padrão: um agente aleatório)
  • wait_for_network_idle (booleano, opcional): Aguardar a atividade de rede estabilizar antes de raspar (padrão: true)
  • custom_elements_to_remove (lista de strings, opcional): Elementos HTML adicionais (seletores CSS) a remover antes da extração
  • grace_period_seconds (float, opcional): Tempo de espera para renderização JS após a navegação. Usa MutationObserver para detecção inteligente. Defina como 0 para pular completamente. (padrão: 0.5)
  • output_format (string, opcional): markdown, text ou html (padrão: markdown)
  • click_selector (string, opcional): Se fornecido, clica no elemento que corresponde a este seletor após a navegação e antes da extração

Retorna:

  • Conteúdo formatado em Markdown extraído da página web, como uma string
  • Erros são relatados como strings começando com [ERROR] ...

Exemplo: Usando click_selector e custom_elements_to_remove

{
  "url": "http://uitestingplayground.com/clientdelay",
  "click_selector": "#ajaxButton",
  "grace_period_seconds": 10,
  "custom_elements_to_remove": [".ads-banner", "#popup"],
  "output_format": "markdown"
}

Prompt: scrape

Parâmetros:

  • url (string, obrigatório): A URL a ser raspada
  • output_format (string, opcional): markdown, text ou html (padrão: markdown)

Retorna:

  • Conteúdo extraído da página web no formato escolhido

Nota:

  • Markdown é retornado por padrão, mas texto ou HTML podem ser solicitados via output_format.
  • O raspador não verifica robots.txt e tentará buscar qualquer URL fornecida.
  • Nenhuma API REST ou ferramenta CLI está incluída; esta é uma ferramenta pura MCP stdio/JSON-RPC.
  • O raspador sempre extrai o conteúdo completo de <body> das páginas web, aplicando apenas remoção essencial de ruído (removendo script, style, nav, footer, aside, header e tags semelhantes sem conteúdo). O raspador detecta e lida com telas de desafio do Cloudflare, retornando uma string de erro específica.

Configuração

Você pode sobrescrever a maioria das opções de configuração usando variáveis de ambiente:

Configurações Principais

  • DEFAULT_TIMEOUT_SECONDS: Timeout para carregamento de páginas e navegação (padrão: 30)
  • DEFAULT_MIN_CONTENT_LENGTH: Comprimento mínimo de conteúdo para texto extraído (padrão: 100)
  • DEFAULT_MIN_CONTENT_LENGTH_SEARCH_APP: Comprimento mínimo de conteúdo para domínios search.app (padrão: 30)
  • DEFAULT_MIN_SECONDS_BETWEEN_REQUESTS: Atraso mínimo entre requisições ao mesmo domínio (padrão: 2)
  • DEFAULT_GRACE_PERIOD_SECONDS: Período de graça padrão para renderização JS (padrão: 0.5)
  • DEBUG_LOGS_ENABLED: Defina como true para habilitar logs de nível debug (padrão: false)

Pool de Navegadores

  • BROWSER_POOL_ENABLED: Habilitar pool de navegadores persistente (padrão: true). Defina como false para lançamento de navegador por requisição (comportamento original).
  • BROWSER_POOL_SIZE: Número de instâncias Chromium para manter ativas (padrão: 2). Cada instância usa ~100-200MB de RAM.

Transporte

  • MCP_TRANSPORT: Modo de transporte — stdio ou streamable-http (padrão: stdio)
  • MCP_HTTP_PORT: Porta do servidor HTTP ao usar transporte streamable-http (padrão: 8080)
  • MCP_HTTP_HOST: Endereço de bind do servidor HTTP (padrão: 0.0.0.0)

Bypass Cloudflare

  • CAPTCHA_API_KEY: Chave de API para serviço de solução de captcha. Quando definida, desafios Cloudflare Turnstile são resolvidos automaticamente. Quando vazia (padrão), páginas protegidas por CF retornam um erro.
  • CAPTCHA_PROVIDER: Provedor de solução de captcha — 2captcha, capsolver ou capmonster (padrão: 2captcha)
  • CAPTCHA_BASE_URL: Endpoint de API personalizado do solver (padrão: usa a URL oficial do provedor)
  • CAPTCHA_TIMEOUT: Timeout em segundos para solução de captcha (padrão: 120)

Configurações de Teste

  • DEFAULT_TEST_REQUEST_TIMEOUT: Timeout para requisições de teste (padrão: 10)
  • DEFAULT_TEST_NO_DELAY_THRESHOLD: Limite para pular atrasos artificiais em testes (padrão: 0.5)

Tratamento de Erros e Limitações

  • O raspador detecta e retorna erros para falhas de navegação, timeouts, erros HTTP (incluindo 404) e desafios anti-bot do Cloudflare.
  • A limitação de taxa é aplicada por domínio (padrão: 2 segundos entre requisições).
  • Bypass Cloudflare: Usa Patchright (anti-detecção em nível CDP) para evasão passiva. A maioria dos sites protegidos por CF é raspada sem acionar um desafio. Quando um desafio Turnstile é acionado e CAPTCHA_API_KEY está definido, ele é resolvido automaticamente via API de terceiros.
  • Limitações:
    • Nenhuma API REST ou ferramenta CLI (apenas MCP stdio/JSON-RPC)
    • Sem suporte para conteúdo não-HTML (PDF, imagens, etc.)
    • Sem autenticação ou gerenciamento de sessão para páginas protegidas
    • Não destinado a raspagem em escala ou violação dos termos do site

Desenvolvimento e Testes

Executando Testes (Docker Compose)

Todos os testes devem ser executados usando Docker Compose. Não execute testes fora do Docker.

  • Todos os testes:
    docker compose up --build --abort-on-container-exit test
    
  • Apenas testes do servidor MCP:
    docker compose up --build --abort-on-container-exit test_mcp
    
  • Apenas testes do raspador:
    docker compose up --build --abort-on-container-exit test_scrapper
    

Executando Benchmarks

docker compose run --rm benchmark

Os resultados são armazenados em benchmarks/RESULTS.md.


Contribuindo

Contribuições são bem-vindas! Por favor, abra issues ou pull requests para correções de bugs, recursos ou melhorias. Se você planeja fazer mudanças significativas, abra uma issue primeiro para discutir sua proposta.


Licença

Este projeto é licenciado sob a Licença MIT.