Web Scraping MCP Server

Busque qualquer página web pública por meio de proxies gerenciados, com renderização de JS opcional e regras de extração.

Documentação

Servidor MCP de Web Scraping

Um servidor Model Context Protocol (MCP) hospedado que dá ao Claude, Cursor, Windsurf e qualquer outro cliente MCP uma ferramenta somente leitura para buscar qualquer página web pública. Ele passa por proxies gerenciados, renderiza JavaScript quando a página precisa, e retorna markdown limpo, texto simples, HTML bruto ou JSON estruturado, sem nada para hospedar e sem navegador na sua stack.

Este é o fallback para sites sem API dedicada. Quando um site tem uma API no catálogo HasData, essa ferramenta retorna campos analisados e esta retorna uma página.

1.000 créditos grátis todo mês, sem cartão necessário. Uma busca simples custa 1 crédito, então o plano gratuito cobre 1.000 delas.

https://mcp.hasdata.com/api/mcp?apis=web_scraping

Glama score tool contract MCP Tools npm PyPI License

Conteúdo

O que você precisa

Um cliente MCP e uma chave de API HasData do painel, grátis para criar sem cartão. Este é um servidor remoto, então o caminho mais simples é uma URL e um cabeçalho x-api-key, sem contêiner para executar. Um cliente que só fala stdio o alcança através de um launcher fino, publicado como @hasdata/web-scraping-mcp no npm e hasdata-web-scraping-mcp no PyPI, mostrado abaixo.

Início rápido

A URL do servidor é a mesma para todos os clientes. Nós o executamos na prática no Claude Code e no Claude Desktop. Os outros blocos seguem o formato documentado de cada cliente para um servidor remoto.

CampoValor
URLhttps://mcp.hasdata.com/api/mcp?apis=web_scraping
TransporteHTTP, transmissível
Cabeçalho de autenticaçãox-api-key: HASDATA_API_KEY

Clientes com suporte a OAuth podem adicionar a mesma URL como um conector e entrar sem colocar uma chave em um arquivo de configuração.

Claude Code
claude mcp add --transport http web-scraping "https://mcp.hasdata.com/api/mcp?apis=web_scraping" \
  --header "x-api-key: HASDATA_API_KEY"
Claude Desktop

Configurações, depois Conectores, depois Adicionar conector personalizado, depois cole https://mcp.hasdata.com/api/mcp?apis=web_scraping e entre.

Para o caminho do arquivo de configuração, o Claude Desktop carrega apenas servidores locais (stdio), então ele alcança um servidor remoto através de um launcher stdio. O pacote @hasdata/web-scraping-mcp é esse launcher, e ele lê a chave do ambiente. Adicione isto ao claude_desktop_config.json:

{
  "mcpServers": {
    "web-scraping": {
      "command": "npx",
      "args": ["-y", "@hasdata/web-scraping-mcp"],
      "env": { "HASDATA_API_KEY": "YOUR_KEY" }
    }
  }
}

Para Python em vez de Node, troque o launcher pelo pacote PyPI, que uvx executa sem instalação manual:

{
  "mcpServers": {
    "web-scraping": {
      "command": "uvx",
      "args": ["hasdata-web-scraping-mcp"],
      "env": { "HASDATA_API_KEY": "YOUR_KEY" }
    }
  }
}
Cursor

~/.cursor/mcp.json para cada projeto, ou .cursor/mcp.json para um:

{
  "mcpServers": {
    "web-scraping": {
      "url": "https://mcp.hasdata.com/api/mcp?apis=web_scraping",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}
Windsurf

~/.codeium/windsurf/mcp_config.json. O Windsurf chama o campo serverUrl, não url:

{
  "mcpServers": {
    "web-scraping": {
      "serverUrl": "https://mcp.hasdata.com/api/mcp?apis=web_scraping",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}
VS Code

.vscode/mcp.json no workspace:

{
  "servers": {
    "web-scraping": {
      "type": "http",
      "url": "https://mcp.hasdata.com/api/mcp?apis=web_scraping",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}

Exemplos de prompts

  • Busque esta página como markdown e resuma-a.
  • Leia esta página de documentação e extraia todos os blocos de código.
  • Obtenha os títulos e links da página inicial deste site como JSON.
  • Esta página carrega seu conteúdo com JavaScript, então renderize-a e aguarde a lista de resultados antes de ler.
  • Busque esta página através de um proxy residencial alemão e me diga se os preços diferem.
  • Tire uma captura de tela desta página.

Uma chamada responde a cada um destes. O que muda entre eles é o quanto do navegador você pediu, e é isso que a chamada custa.

Ferramentas

Uma ferramenta. O custo depende do que você ativa, e a tabela está em Preços.

Raspar página web

hasdata_web_scraping_web_scraping_scrapeWebPage

Busca uma URL.

ParâmetroTipoObrigatórioObservações
urlstringsimA página a buscar
outputFormatarrayQualquer um de markdown, text, html, json. Veja Formatos de saída
jsRenderingbooleanRenderiza a página em um navegador. Ativado por padrão, e a principal alavanca de custo
proxyTypestringdatacenter ou residential
proxyCountrystringUS, UK, DE, IE, FR, IT, SE, BR, CA, JP, SG, IN ou ID
headersobjectCabeçalhos de requisição personalizados
waitnumberMilissegundos para aguardar após o carregamento
waitForstringSeletor CSS para aguardar antes de ler
jsScenarioarrayAções para executar na página. Veja abaixo
extractRulesobjectSeletores CSS para extrair campos nomeados
aiExtractRulesobjectUm esquema tipado que um LLM preenche a partir da página
extractLinksbooleanColeta os links da página
extractEmailsbooleanColeta endereços de e-mail na página
screenshotbooleanCaptura a página renderizada
blockResourcesbooleanIgnora imagens e folhas de estilo
blockAdsbooleanIgnora requisições de anúncios
blockUrlsarrayIgnora estas URLs
includeOnlyTagsarrayMantém apenas elementos que correspondem a estes seletores
excludeTagsarrayRemove elementos que correspondem a estes seletores
removeBase64ImagesbooleanRemove imagens base64 inline da saída

extractRules mapeia um nome de campo para um seletor CSS, com @attr para ler um atributo em vez de texto.

{ "title": "h1", "link_href": "a#link @href", "page_text": "body" }

jsScenario é um array de ações executadas em ordem, cobrindo click, wait, waitFor, waitForAndClick, scrollX, scrollY, fill e evaluate para JavaScript arbitrário. Ele precisa de jsRendering ativado.

aiExtractRules descreve a forma que você quer e permite que um modelo a preencha a partir do HTML. Cada chave é um campo de saída, tipado como string, number, boolean, list ou item para um objeto aninhado.

Formatos de saída

Esta é a parte que vale a pena ler antes da sua primeira chamada, porque a forma da resposta muda com outputFormat.

Peça exatamente um de markdown, text ou html, e o conteúdo chega como uma string simples em text no nível superior.

{
  "url": "https://api.hasdata.com/scrape/web/",
  "status": 200,
  "json": null,
  "text": "# Example Domain\n\nThis domain is for use in documentation examples without needing permission. Avoid use in operations.\n\n[Learn more](https://iana.org/domains/example)\n"
}

Inclua json, sozinho ou junto com outro formato, e tudo se move para dentro de json, o text de nível superior se torna null, e os formatos solicitados se tornam chaves lá dentro, ao lado dos metadados da página.

{
  "json": {
    "requestMetadata": { "id": "7764031a-43f7-4102-8561-a7b7a6f1cbf5", "status": "ok" },
    "statusCode": 200,
    "statusText": "OK",
    "headers": { "server": "nginx", "content-type": "text/html; charset=utf-8" },
    "extractedData": { "title": "Hacker News", "firstStory": ["iPhone Duo", "apple.com", "Show HN: What if the speed of light was 5 km/h?"] }
  },
  "text": null
}

extractedData contém os resultados de extractRules. Um seletor que corresponde a vários elementos retorna todos eles como um array, então .titleline a em uma página de listagem retorna cada correspondência em vez da primeira.

Erros e caminhos de falha

Planeje para estes em vez de assumir um caminho feliz.

extractLinks e extractEmails não fazem nada a menos que outputFormat inclua json. Eles colocam links e emails dentro do objeto json, e não há lugar para eles em uma resposta markdown simples. Pedi-los com outputFormat: ["text"] retorna o texto e silenciosamente sem links.

Um 404 ou 403 na página alvo é uma chamada bem-sucedida. O status da própria página volta como statusCode dentro de json, ou como status no nível superior, e a requisição é cobrada de qualquer forma. Verifique o status antes de analisar o corpo.

jsRendering está ativado por padrão, e é isso que a chamada custa. Desligá-lo leva uma busca de 10 créditos para 1. A maioria das páginas estáticas, documentação, artigos e qualquer coisa renderizada no servidor não precisa disso. Ative-o quando o conteúdo chegar vazio sem ele.

waitFor vence wait. Um atraso fixo é um palpite que é ou curto demais em um carregamento lento ou desperdiçado em um rápido. Um seletor CSS espera pela coisa que você realmente precisa e retorna assim que ela aparece.

Um proxy residencial custa de cinco a quinze vezes o preço de um de datacenter. Use-o quando uma busca de datacenter voltar bloqueada, em vez de como padrão.

includeOnlyTags e excludeTags aceitam seletores querySelectorAll. Um seletor inválido não restringe nada em vez de gerar erro, então uma resposta suspeitamente completa é o sintoma de um erro de digitação.

aiExtractRules executa um modelo sobre o HTML, então não é nem grátis nem determinístico. Duas chamadas na mesma página podem diferir na redação. Quando um seletor CSS pode fazer o trabalho, extractRules é mais barato e repetível.

Resultados que carregam dados também carregam um requestMetadata.id que vale citar no suporte.

Preços, plano gratuito e limites

O custo depende de dois interruptores, e nada mais o muda.

Proxy de datacenterProxy residencial
jsRendering: false1 crédito5 créditos
jsRendering: true10 créditos15 créditos

A renderização está ativada por padrão, então uma chamada não configurada custa 10. Uma página estática buscada com jsRendering: false custa 1, o que torna esta a ferramenta mais barata do catálogo quando você não precisa de um navegador.

O plano gratuito é 1.000 créditos todo mês sem cartão. Isso é 1.000 buscas simples, ou 100 renderizadas. Ele renova com o ciclo de cobrança.

Planos pagos começam em $49 por mês para 200.000 créditos, o que é 200.000 buscas simples ou 20.000 renderizadas. O preço unitário cai com o volume nos planos de alto volume.

Seu plano também define a concorrência. O plano gratuito permite 1 requisição por vez, Startup 15, Business 30, Growth 50, e os planos de alto volume vão de 200 a 1.500. Tente novamente no 429 com backoff em qualquer coisa não supervisionada, porque um agente rastejando uma lista de URLs alcançará o teto antes de você.

Créditos são descontados apenas de requisições bem-sucedidas. Uma página que responde 404 ainda é uma busca bem-sucedida de um 404.

Como se compara

A comparação que vale a pena fazer é contra buscar a página você mesmo, e contra as outras ferramentas deste catálogo.

fetch no seu próprio códigoUma ferramenta HasData dedicadaEste servidor
Bloqueado por proteção de botFrequentementeTratadoTratado
Páginas com muito JavaScriptPrecisa de um navegador que você executaTratadoUm parâmetro
Segmentação geográficaSeus próprios proxiesIntegradoUm parâmetro
SaídaHTML brutoCampos analisados para aquele siteMarkdown, texto, HTML ou JSON
CoberturaQualquer coisaOs sites com uma ferramentaQualquer coisa pública
CustoSua infraestruturaPor chamadaA partir de 1 crédito por chamada

A linha que decide contra uma ferramenta dedicada é a cobertura. Amazon, Zillow, Yelp e o resto retornam campos tipados porque alguém mantém um parser para aquele site. Este retorna uma página de qualquer site e deixa a análise para você, o que é a troca certa apenas quando nenhuma ferramenta dedicada existe.

Contra seu próprio fetch, a questão é se o alvo revida. Para uma página amigável, seu próprio código é grátis e isto não vale um crédito.

FAQ

O que é um servidor MCP de web scraping?

Um servidor MCP expõe ferramentas que um cliente de IA pode chamar. Este permite que um agente busque qualquer URL pública por meio de proxies gerenciados e a receba de volta como markdown, texto, HTML ou JSON estruturado, sem precisar de um navegador ou de um pool de proxies na sua stack.

Preciso dos meus próprios proxies ou de um navegador headless?

Não. Ambos estão no lado do servidor. A única credencial é a sua chave HasData.

Como posso tornar as chamadas mais baratas?

Defina jsRendering: false. Essa é a diferença entre 10 créditos e 1. Adicione blockResources quando precisar de renderização, para que o navegador ignore imagens e folhas de estilo.

Como sei se uma página precisa de renderização?

Busque-a uma vez sem renderização, por 1 crédito. Se o conteúdo que você quer estiver lá, pronto. Se o corpo voltar como uma casca vazia, renderize-a.

Ela consegue preencher um formulário ou clicar para ir para a próxima página?

Sim, com jsScenario, que executa as etapas click, fill, waitFor, scrollY e evaluate em ordem na página renderizada.

Qual é a diferença entre extractRules e aiExtractRules?

extractRules usa seletores CSS, e é barato, rápido e repetível. aiExtractRules descreve os campos que você quer e permite que um modelo leia a página, o que lida com páginas cuja estrutura você não consegue fixar, mas custa mais e pode variar entre execuções.

Posso obter uma captura de tela?

Sim, com screenshot: true em uma chamada renderizada.

Posso usar isso junto com outras APIs HasData?

Sim. Uma chave cobre tudo, e um endpoint atende a todos por meio do parâmetro apis. Aponte um cliente para ?apis=web_scraping,google_serp para obter os dois conjuntos de ferramentas em uma única conexão, ou para mcp.hasdata.com/api/mcp para o catálogo completo.

A HasData é afiliada aos sites que eu busco?

Não. A HasData é um serviço independente. Esta ferramenta busca páginas que você indica, então o que volta é o que esse site publica, e você é responsável por usá-lo de acordo com os termos desse site e a lei que se aplica a você.

Conformidade e dados pessoais

Esta ferramenta aponta para onde você apontar, o que coloca mais responsabilidade sobre você do que uma ferramenta específica de um site. Duas coisas merecem uma decisão antes de você construir. extractEmails coleta endereços, e um endereço é um dado pessoal no sentido do GDPR e regulamentado separadamente novamente para marketing sob a Lei CAN-SPAM, as regras de ePrivacy e seus equivalentes. E uma página atrás de login, paywall ou exclusão por robots não se torna pública pelo fato de um proxy conseguir alcançá-la. Busque o que é genuinamente público, mantenha apenas o que seu propósito precisa e verifique suas próprias obrigações.

Links HasData

Outros servidores MCP HasData: Google Search, Google Images, Google Scholar, Google Maps, Google Trends, Bing, DuckDuckGo, YouTube, TikTok, Instagram, Amazon, Walmart, Shopify, Yelp, Yellow Pages, Zillow, Redfin, Airbnb, Booking.com, Indeed, Glassdoor.

Desenvolvimento

O lançador é uma ponte stdio fina para o servidor remoto, então não há nada para compilar.

npm install
HASDATA_API_KEY=your_key_here npm test

Os testes em test/ verificam o contrato da ferramenta, a parte que pode quebrar sem um commit aqui. Eles verificam que ?apis=web_scraping retorna a única ferramenta esperada, que seu nome não mudou, que ainda exige url e carrega uma descrição, que os parâmetros documentados neste README ainda estão no esquema e que a chave em uso é realmente aceita.

Dois testes fixam o comportamento do formato de saída, porque é a parte deste README que um leitor tem mais probabilidade de ser pego e a parte que uma refatoração tem mais probabilidade de mudar. Um pede apenas markdown e verifica que o conteúdo chega como uma string no nível superior. O outro pede json com extractRules e verifica que a extração chega em extractedData dentro de json. Ambos rodam sem renderização, então o par custa 2 créditos.

A suíte de contrato também roda semanalmente em um cronograma, porque a lista de ferramentas upstream pode mudar sem que ninguém toque neste repositório.

Contribuindo

Uma tabela de ferramentas, uma amostra de resposta ou um comportamento documentado que não corresponde à realidade vale uma issue. Há um modelo exatamente para isso. Pull requests são bem-vindos para o mesmo e para qualquer coisa no lançador.

Licença

MIT, veja LICENSE.