SPB Git forge

spb/trawls

Public
3commits 1branches 0releases
456.0 KBsize
maindefault branch
18 days agolast push
Python 76.2% JavaScript 11.3% CSS 6.3% HTML 5.9%
4.6 KB

# Trawls — www.trawls.dev

Moteur de crawling, d'extraction et de navigation web, construit from scratch. Un chalut (trawl) ratisse le fond et remonte tout : Trawls cartographie et extrait n'importe quel site et renvoie du Markdown propre, LLM-ready.

  • Ne crashe jamais : une page qui échoue produit un PageResult status=failed avec une erreur typée. Le crawl continue.
  • Escalade automatique : HTTP pur (curl_cffi, empreinte TLS Chrome) → navigateur (Playwright, pool de contexts) → stealth (patches JS, identité cohérente). Le mode résolu est mémorisé par host.
  • Sortie LLM-ready : pipeline HTML → Markdown maison (nettoyage, suppression du boilerplate, scoring du contenu principal, tables avec rowspan/colspan, citations), métadonnées fusionnées (head, OpenGraph, JSON-LD), chunks par titres ou par tokens.
  • PDF : texte avec ordre de lecture, titres inférés, tables, détection de scan (OCR optionnel).
  • Extraction structurée : CSS typé (déterministe) ou LLM (JSON Schema, validation, corrections) avec fusion multi-pages.
  • Self-host first : SQLite, worker embarqué, aucun service externe requis. LLM local via Ollama par défaut.
  • Observable : structlog JSON, /healthz, /readyz, /metrics Prometheus, trace d'escalade par page.

# Démarrage

bash
uv venv --python 3.12 && source .venv/bin/activate
uv pip install -e ".[dev]"
playwright install chromium
trawls serve            # http://localhost:8180 (UI + API + worker)
bash
trawls scrape https://fr.wikipedia.org/wiki/Chalut
trawls map https://docs.python.org --search "asyncio"
trawls crawl https://exemple.com --max-pages 50 -o pages.jsonl

Docker : make up (api + web sur http://localhost:8180).

# API (/v1, OpenAPI sur /docs)

Méthode Route Rôle
POST /scrape une page, synchrone → PageResult
POST /crawl → GET /crawl/{id} · /crawl/{id}/stream (SSE) · DELETE crawl asynchrone, pages streamées
POST /map liste d'URLs (sitemaps + crawl shallow), tri BM25 si search
POST /extract CSS ou LLM sur urls[] / pattern ; sync ≤ 5 URLs
POST /batch/scrape N URLs en job
GET /jobs, /jobs/{id}, /jobs/{id}/stream, /jobs/{id}/export?format=zip|jsonl|md jobs génériques
GET /usage · /keys (admin) crédits, clés API (argon2, affichées une fois)

Erreurs : { "error": { "code", "message", "retryable", "details?" } }. Idempotence : header Idempotency-Key. Webhooks signés X-Trawls-Signature (HMAC-SHA256).

bash
curl -s https://www.trawls.dev/v1/scrape -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com","formats":["markdown","links"]}' | jq .markdown

# Configuration (préfixe TRAWLS_)

PORT (8180), PUBLIC_URL, DATA_DIR, REQUIRE_AUTH, ADMIN_KEY, BROWSER_POOL_SIZE, MAX_CONCURRENCY_PER_HOST, MAX_SIZE_MB, PROXY_URLS, LLM_PROVIDER (openai|anthropic|none), LLM_BASE_URL (Ollama par défaut), LLM_API_KEY, LLM_MODEL, RESULT_TTL_DAYS, RATE_LIMIT_PER_MINUTE, ALLOW_PRIVATE_TARGETS (jamais en prod). Voir .env.example.

# Architecture

text
trawls/
  config.py            settings pydantic
  models/              contrat Pydantic v2 (ScrapeOptions, PageResult, ErrorInfo…)
  core/fetcher/        http_fast (curl_cffi), browser (pool Playwright), strategy (escalade)
  core/antibot/        detect, identity, stealth, blocklist
  core/scheduler/      dedup (normalisation + simhash), robots, politeness
  core/resilience/     retry, breaker, budget
  core/security.py     garde SSRF (DNS résolu avant, re-vérifié après redirection)
  core/scrape.py       pipeline d'une page — ne lève jamais
  processors/          html_to_md (clean, readability, convert, tables, citations), pdf, structured, chunker, links
  extract/             css, llm, merge
  map/                 sitemaps + crawl shallow + BM25
  llm/                 client unique (Anthropic, OpenAI-compatible)
  worker/              store SQLite, moteur de jobs (crawl/batch/extract), SSE
  api/                 FastAPI /v1, auth, UI
  web/static/          UI (playground, crawls, map, extract, keys)
  cli.py

# Tests

bash
pytest -q                 # unitaires (html_to_md, dedup, ssrf, detect, chunker, css)
ruff check . && ruff format --check .

# Déploiement MacLustr

Déployée via mld (manifeste trawls.json) : PM2 trawls-api + trawls-ngrokhttps://www.trawls.dev. Voir deploy/trawls.manifest.json.

# Feuille de route

Phases 1–6 livrées (fetch + escalade, Markdown, API/jobs/SSE/CLI, map + PDF, extract + chunker, UI). Phase 7 (agent) et 8 (SDK, benchmarks) à venir — voir CLAUDE.md.