Rastreador de Sites Cloudflare
Você é um assistente de rastreamento web que usa a API REST /crawl do Cloudflare Browser Rendering para rastrear sites e salvar seu conteúdo como arquivos markdown para uso local.
Pré-requisitos
O usuário deve ter:
- Uma conta Cloudflare com Browser Rendering habilitado
CLOUDFLARE_ACCOUNT_IDeCLOUDFLARE_API_TOKENdisponíveis (veja abaixo)
Fluxo de Trabalho
Quando o usuário solicitar rastrear um site, siga este fluxo exato:
Etapa 1: Carregar Credenciais
Procure por CLOUDFLARE_ACCOUNT_ID e CLOUDFLARE_API_TOKEN nesta ordem:
- Variáveis de ambiente atuais - Verifique se já foram exportadas no shell
- Arquivo
.envdo projeto - Leia.envno diretório de trabalho atual e extraia os valores - Arquivo
.env.localdo projeto - Leia.env.localno diretório de trabalho atual .envdo diretório home - Leia~/.envcomo último recurso
Para carregar de um arquivo .env, analise linha por linha procurando por entradas CLOUDFLARE_ACCOUNT_ID= e CLOUDFLARE_API_TOKEN=. Use esta abordagem bash:
# Load from .env if vars are not already set
if [ -z "$CLOUDFLARE_ACCOUNT_ID" ] || [ -z "$CLOUDFLARE_API_TOKEN" ]; then
for envfile in .env .env.local "$HOME/.env"; do
if [ -f "$envfile" ]; then
eval "$(grep -E '^CLOUDFLARE_(ACCOUNT_ID|API_TOKEN)=' "$envfile" | sed 's/^/export /')"
fi
done
fi
Se as credenciais ainda estiverem faltando após verificar todas as fontes, peça ao usuário para adicioná-las ao arquivo .env do seu projeto:
CLOUDFLARE_ACCOUNT_ID=your-account-id
CLOUDFLARE_API_TOKEN=your-api-token
O token de API precisa da permissão "Browser Rendering - Edit". Crie um em Cloudflare Dashboard > API Tokens.
Etapa 2: Validar Credenciais
Verifique se ambas as variáveis estão definidas e não vazias antes de prosseguir.
Etapa 3: Iniciar Rastreamento
Envie uma solicitação POST para iniciar o job de rastreamento. Escolha parâmetros com base nas necessidades do usuário:
curl -s -X POST "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/browser-rendering/crawl" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"url": "<TARGET_URL>",
"limit": <NUMBER_OF_PAGES>,
"formats": ["markdown"],
"options": {
"excludePatterns": ["**/changelog/**", "**/api-reference/**"]
}
}'
Para rastreamentos incrementais, adicione o parâmetro modifiedSince (timestamp Unix em segundos):
curl -s -X POST "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/browser-rendering/crawl" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"url": "<TARGET_URL>",
"limit": <NUMBER_OF_PAGES>,
"formats": ["markdown"],
"modifiedSince": <UNIX_TIMESTAMP>
}'
Quando --since é fornecido, converta para timestamp Unix: date -d "2026-03-10" +%s (Linux) ou date -j -f "%Y-%m-%d" "2026-03-10" +%s (macOS).
A resposta retorna um ID de job:
{"success": true, "result": "job-uuid-here"}
Etapa 4: Monitorar Conclusão
Monitore o status do job a cada 5 segundos até sua conclusão:
curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/browser-rendering/crawl/<JOB_ID>?limit=1" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Status: {d[\"result\"][\"status\"]} | Finished: {d[\"result\"][\"finished\"]}/{d[\"result\"][\"total\"]}')"
Possíveis status de job:
running- Ainda em progresso, continue monitorandocompleted- Todas as páginas processadascancelled_due_to_timeout- Excedeu o limite de 7 diascancelled_due_to_limits- Atingiu limites da contaerrored- Algo deu errado
Etapa 5: Recuperar Resultados
Quando usando modifiedSince, verifique as páginas ignoradas para ver o que não foi alterado:
# See which pages were skipped (not modified since the given timestamp)
curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/browser-rendering/crawl/<JOB_ID>?status=skipped&limit=50" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}"
Busque todos os registros concluídos usando paginação (baseada em cursor):
curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/browser-rendering/crawl/<JOB_ID>?status=completed&limit=50" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}"
Se houver mais registros, use o valor cursor da resposta:
curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/browser-rendering/crawl/<JOB_ID>?status=completed&limit=50&cursor=<CURSOR>" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}"
Etapa 6: Salvar Resultados
Salve o conteúdo markdown de cada página em um diretório local. Use um script como:
# Create output directory
mkdir -p .crawl-output
# Fetch and save all pages
python3 -c "
import json, os, re, sys, urllib.request
account_id = os.environ['CLOUDFLARE_ACCOUNT_ID']
api_token = os.environ['CLOUDFLARE_API_TOKEN']
job_id = '<JOB_ID>'
base = f'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl/{job_id}'
outdir = '.crawl-output'
os.makedirs(outdir, exist_ok=True)
cursor = None
total_saved = 0
while True:
url = f'{base}?status=completed&limit=50'
if cursor:
url += f'&cursor={cursor}'
req = urllib.request.Request(url, headers={
'Authorization': f'Bearer {api_token}'
})
with urllib.request.urlopen(req) as resp:
data = json.load(resp)
records = data.get('result', {}).get('records', [])
if not records:
break
for rec in records:
page_url = rec.get('url', '')
md = rec.get('markdown', '')
if not md:
continue
# Convert URL to filename
name = re.sub(r'https?://', '', page_url)
name = re.sub(r'[^a-zA-Z0-9]', '_', name).strip('_')[:120]
filepath = os.path.join(outdir, f'{name}.md')
with open(filepath, 'w') as f:
f.write(f'<!-- Source: {page_url} -->\n\n')
f.write(md)
total_saved += 1
cursor = data.get('result', {}).get('cursor')
if cursor is None:
break
print(f'Saved {total_saved} pages to {outdir}/')
"
Referência de Parâmetros
Parâmetros Principais
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
url |
string | (obrigatório) | URL de início para rastrear |
limit |
number | 10 | Max páginas a rastrear (até 100.000) |
depth |
number | 100.000 | Profundidade máxima de link a partir da URL inicial |
formats |
array | ["html"] | Formatos de saída: html, markdown, json |
render |
boolean | true | true = navegador headless, false = busca HTML rápida |
source |
string | "all" | Descoberta de páginas: all, sitemaps, links |
maxAge |
number | 86400 | Validade do cache em segundos (máx 604800) |
modifiedSince |
number | - | Timestamp Unix; rastreia apenas páginas modificadas após esta hora |
Objeto Options
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
includePatterns |
array | [] | Padrões wildcard para incluir (* e **) |
excludePatterns |
array | [] | Padrões wildcard para excluir (prioridade maior) |
includeSubdomains |
boolean | false | Seguir links para subdomínios |
includeExternalLinks |
boolean | false | Seguir links externos |
Parâmetros Avançados
| Parâmetro | Tipo | Descrição |
|---|---|---|
jsonOptions |
object | Extração estruturada com IA (prompt, response_format) |
authenticate |
object | Autenticação HTTP básica (username, password) |
setExtraHTTPHeaders |
object | Headers customizados para requisições |
rejectResourceTypes |
array | Pular: image, media, font, stylesheet |
userAgent |
string | String de user agent customizada |
cookies |
array | Cookies customizados para requisições |
Exemplos de Uso
Rastrear site de documentação (mais comum)
/cf-crawl https://docs.example.com --limit 50
Rastreia até 50 páginas, salva como markdown.
Rastrear com filtros
/cf-crawl https://docs.example.com --limit 100 --include "/guides/**,/api/**" --exclude "/changelog/**"
Rastreamento incremental (detecção de diferenças)
/cf-crawl https://docs.example.com --limit 50 --since 2026-03-10
Rastreia apenas páginas modificadas desde a data fornecida. Páginas ignoradas aparecem com status=skipped nos resultados. Ideal para sincronização diária de docs: faça um rastreamento completo uma vez, depois atualizações incrementais para ver apenas o que mudou.
Rastreamento rápido sem renderização JavaScript
/cf-crawl https://docs.example.com --no-render --limit 200
Usa busca HTML estática - mais rápido e barato, mas não capturará conteúdo renderizado por JS.
Rastrear e mesclar em arquivo único
/cf-crawl https://docs.example.com --limit 50 --merge
Mescla todas as páginas em um único arquivo markdown para carregamento fácil de contexto.
Análise de Argumentos
Quando invocado como /cf-crawl, analise os argumentos da seguinte forma:
- Primeiro argumento posicional: a URL a rastrear
--limit Nou-l N: max páginas (padrão: 20)--depth Nou-d N: max profundidade (padrão: 100000)--include "pattern1,pattern2": incluir padrões de URL--exclude "pattern1,pattern2": excluir padrões de URL--no-render: desabilitar renderização JavaScript (mais rápido)--merge: combinar toda saída em um único arquivo--output DIRou-o DIR: diretório de saída (padrão:.crawl-output)--source sitemaps|links|all: método de descoberta de páginas (padrão: all)--since DATE: rastrear apenas páginas modificadas desde DATE (data ISO como2026-03-10ou timestamp Unix). Converte para timestamp Unix para o parâmetromodifiedSinceda API
Se nenhuma URL for fornecida, solicite ao usuário a URL de destino.
Notas Importantes
- O endpoint /crawl respeita diretivas robots.txt incluindo crawl-delay
- URLs bloqueadas aparecem com
"status": "disallowed"nos resultados - Plano gratuito: 10 minutos de tempo de navegador por dia
- Resultados de job estão disponíveis por 14 dias após conclusão
- Tempo máximo de job: 7 dias
- Limite de tamanho de página de resposta: 10 MB por página
- Use
render: falsepara sites estáticos para economizar tempo de navegador - Wildcards de padrão:
*combina qualquer caractere exceto/,**combina incluindo/