Skip to main content

matrx-scraper

Web scraping, HTML parsing, site crawling, headless-browser automation, and search for Python. An 8-stage parser turns raw HTML into clean AI-ready content plus structured extractions (tables, code blocks, categorized links, metadata, schema.org). It runs standalone with no database, and scales up to a full FastAPI microservice with a durable crash-safe crawl frontier.

Install

pip install matrx-scraper                  # core: HTTP fetch + parse + crawl + Brave Search
pip install "matrx-scraper[browser]"       # + Playwright / curl_cffi for JS-rendered pages
pip install "matrx-scraper[metadata]"      # + extruct (JSON-LD, microdata, RDFa, OpenGraph)
pip install "matrx-scraper[dedup]"         # + MinHash / SimHash near-duplicate detection
pip install "matrx-scraper[pdf]"           # + PyMuPDF
pip install "matrx-scraper[ocr]"           # + Tesseract
pip install "matrx-scraper[db]"            # + matrx-orm persistence
pip install "matrx-scraper[durable]"       # + matrx-runtime crash-safe crawl frontier
pip install "matrx-scraper[server]"        # + FastAPI microservice (includes browser, db, metadata, durable)
pip install "matrx-scraper[all]"           # everything

Python 3.12+. Hard deps are a small set of well-known libraries (httpx, beautifulsoup4, selectolax, markdownify, tldextract, tabulate, croniter, python-dotenv) plus matrx-utils and matrx-files. Everything heavy sits behind an extra so lean installs stay lean.

Quickstart

from matrx_scraper import scrape, scrape_many_stream, parse_html, audit_html

result = await scrape("https://example.com/article")
result.success           # bool  — outcome
result.failure_reason    # str | None
result.title
result.ai_content        # clean, AI-ready markdown
result.links             # links by category
result.tables            # parsed tables
result.organized_data    # structured JSON of the page

# Many URLs — yields each page as it finishes, never a buffered batch.
async for page in scrape_many_stream(urls, concurrency=5):
    print(page.url, page.success)

parsed = parse_html(open("page.html").read())   # no network
seo = audit_html(html, url)                      # full page evidence in one parse

Crawl a site

from matrx_scraper import crawl_site

async for page in crawl_site("https://example.com", max_pages=100):
    print(page.url, page.title)

Drive a browser

from matrx_scraper.ai_browser import navigate, type_text, wait_for, screenshot, close_session

nav = await navigate("https://example.com/login", extract_text=True)
await type_text(nav.session_id, "input[name=email]", "user@example.com")
await wait_for(nav.session_id, selector="[data-ready]", timeout_ms=15_000)
shot = await screenshot(nav.session_id, full_page=True)
await close_session(nav.session_id)

Every action returns a Pydantic result with success: bool plus error_type / error_message, so an agent loop recovers from timeouts and selector misses without exception handling.

Other clients

BraveSearchClient (search), PsiClient (PageSpeed Insights v5), GscClient (Google Search Console), compute_link_scores (PageRank over a link graph), CustomExtractor (per-host CSS/XPath/regex/JSON-LD rules), quick_preview (robots + homepage audit + screenshot). All pure — they return typed values and persist nothing.

AI tools and MCP

matrx_scraper.ai_tools.ALL_TOOLS is 22 ToolSpec descriptors (14 browser, 4 scrape, 4 crawl), each with a full JSON Schema and an async handler — drop them straight into an OpenAI/Anthropic tool call or any agent registry.

The bundled MCP server exposes the same list:

python -m matrx_scraper.mcp            # stdio (canonical MCP transport)
python -m matrx_scraper.mcp --list     # print registered tools and exit
python -m matrx_scraper.mcp --groups browser,scrape

stdio is the only transport. The MCP server has no network listener by design — one would hand a JS-executing browser to anyone who can reach the port. Network callers use the authenticated microservice below.

Running the microservice

# Docker (build context is the monorepo root, so sibling packages resolve)
cd packages/matrx-scraper && cp .env.example .env && docker compose up -d

# Or directly
pip install "matrx-scraper[server]" && playwright install chromium
matrx-scraper --port 8000
Variable Required Purpose
SUPABASE_MATRIX_{HOST,PORT,DATABASE_NAME,USER,PASSWORD} yes The one connection, required. Both scraper.* (cache / domain config / retry queue) and the canonical web.* crawler bind here. Point these five at your own Postgres to run the scraper on its own database; there is never a second variable and never a fallback chain.
SUPABASE_MATRIX_URL yes Project URL; also derives the JWT JWKS URL
SUPABASE_JWT_SECRET yes HS256 compatibility (ES256 verifies via JWKS)
DATACENTER_PROXIES for proxied fetches Comma-separated pool. Missing or exhausted fails loudly — never a silent direct request that exposes the host IP.
ADMIN_API_TOKEN for server-to-server Shared secret for the approved-server identity
BRAVE_SEARCH_API_KEY_PRO_AI for search The one platform Brave key; explicit api_key injection supports user-supplied keys.
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_REGION / AWS_S3_DEFAULT_BUCKET for the canonical crawler Artifact bytes via matrx-files
PORT / WORKERS / LOG_LEVEL no Defaults 8000 / 1 / info

Everything mounts under /api/scraper/: quick-scrape · batch · search · search-and-scrape · browser-fetch · browser/* (16 session endpoints) · preview · content/save · queue/* · config/domains · crawler/*. GET /health (reports the installed version) and GET /health/ready are public; everything else takes Authorization: Bearer <supabase-jwt>.

Embed it in another FastAPI app instead:

from matrx_scraper.server import create_app, ServerConfig

app = create_app(ServerConfig.from_env())   # DB comes from SUPABASE_MATRIX_*, never a config URL

Extending it in a host

The crawler takes four injection points; defaults are in-memory / no-op / discard, so nothing is required to get started:

Protocol Default Swap in
CrawlEventSink NoopEventSink your durable event writer
QueueBackend InMemoryQueueBackend the [durable] runtime frontier — survives restarts
BodyPersister discard your storage
RecipeBackend StaticRecipeBackend(DEFAULT_RECIPES) your per-host Playwright playbooks

Host objects (cache, domain config, browser pool, file manager, work-queue factory) are handed over with matrx_scraper.configure_ext(...); DB models bind to an existing matrx-orm pool with matrx_scraper.configure_db("<db name>").

Documentation

Doc For
matrx_scraper/FEATURE.md Engine contract: SSRF gates, proxy rules, browser runtimes, tool surface, auth, persistence
matrx_scraper/web_crawl/FEATURE.md The canonical site crawler
CLAUDE.md Contributing to the package

License

MIT. Developed in the aidream monorepo.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

matrx_scraper-0.2.110.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

matrx_scraper-0.2.110-py3-none-any.whl (833.0 kB view details)

Uploaded Python 3

File details

Details for the file matrx_scraper-0.2.110.tar.gz.

File metadata

  • Download URL: matrx_scraper-0.2.110.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for matrx_scraper-0.2.110.tar.gz
Algorithm Hash digest
SHA256 fbed84f00c4006f0d51a1e51bd11a22e3b95a0fcc33cb5dd8c808d3dafa3a5a0
MD5 ad36299951214ea738f62188ad951aeb
BLAKE2b-256 41cac4e5bed2ecf01817a501aa4cc7c7571a937003cd867347b6a7d9810ca9d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for matrx_scraper-0.2.110.tar.gz:

Publisher: publish-package.yml on AI-Matrix-Engine/aidream

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file matrx_scraper-0.2.110-py3-none-any.whl.

File metadata

  • Download URL: matrx_scraper-0.2.110-py3-none-any.whl
  • Upload date:
  • Size: 833.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for matrx_scraper-0.2.110-py3-none-any.whl
Algorithm Hash digest
SHA256 8aae5190c5e6d34da2da2aa59fb2cc3b7e1531de6cd8d5668b867f16ffe3d7e3
MD5 01cb0c678610124971a5e0560b1b7680
BLAKE2b-256 fc14ef413bc96f7c47ed874fccc18e60e6238b080c776e4c7b921b003ad62f6b

See more details on using hashes here.

Provenance

The following attestation bundles were made for matrx_scraper-0.2.110-py3-none-any.whl:

Publisher: publish-package.yml on AI-Matrix-Engine/aidream

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.152

2 files

0.2.151

2 files

0.2.150

2 files

0.2.149

2 files

0.2.148

2 files

0.2.147

2 files

0.2.146

2 files

0.2.145

2 files

0.2.144

2 files

0.2.143

2 files

0.2.142

2 files

0.2.141

2 files

0.2.140

2 files

0.2.139

2 files

0.2.138

2 files

0.2.137

2 files

0.2.136

2 files

0.2.135

2 files

0.2.134

2 files

0.2.133

2 files

0.2.132

2 files

0.2.131

2 files

0.2.130

2 files

0.2.129

2 files

0.2.128

2 files

0.2.127

2 files

0.2.126

2 files

0.2.125

2 files

0.2.124

2 files

0.2.123

2 files

0.2.122

2 files

0.2.121

2 files

0.2.120

2 files

0.2.119

2 files

0.2.118

2 files

0.2.117

2 files

0.2.116

2 files

0.2.115

2 files

0.2.114

2 files

0.2.113

2 files

0.2.112

2 files

0.2.111

2 files

This release

0.2.110 This release

2 files

0.2.109

2 files

0.2.108

2 files

0.2.107

2 files

0.2.106

2 files

0.2.105

2 files

0.2.104

2 files

0.2.103

2 files

0.2.102

2 files

0.2.101

2 files

0.2.100

2 files

0.2.99

2 files

0.2.98

2 files

0.2.97

2 files

0.2.96

2 files

0.2.95

2 files

0.2.94

2 files

0.2.93

2 files

0.2.92

2 files

0.2.91

2 files

0.2.90

2 files

0.2.89

2 files

0.2.88

2 files

0.2.87

2 files

0.2.86

2 files

0.2.85

2 files

0.2.84

2 files

0.2.83

2 files

0.2.82

2 files

0.2.81

2 files

0.2.80

2 files

0.2.79

2 files

0.2.78

2 files

0.2.77

2 files

0.2.76

2 files

0.2.75

2 files

0.2.74

2 files

0.2.73

2 files

0.2.72

2 files

0.2.71

2 files

0.2.70

2 files

0.2.69

2 files

0.2.68

2 files

0.2.67

2 files

0.2.66

2 files

0.2.65

2 files

0.2.64

2 files

0.2.63

2 files

0.2.62

2 files

0.2.61

2 files

0.2.60

2 files

0.2.59

2 files

0.2.58

2 files

0.2.57

2 files

0.2.56

2 files

0.2.55

2 files

0.2.54

2 files

0.2.53

2 files

0.2.52

2 files

0.2.51

2 files

0.2.50

2 files

0.2.49

2 files

0.2.48

2 files

0.2.47

2 files

0.2.46

2 files

0.2.45

2 files

0.2.44

2 files

0.2.43

2 files

0.2.42

2 files

0.2.41

2 files

0.2.40

2 files

0.2.39

2 files

0.2.38

2 files

0.2.37

2 files

0.2.36

2 files

0.2.35

2 files

0.2.34

2 files

0.2.33

2 files

0.2.32

2 files

0.2.31

2 files

0.2.30

2 files

0.2.29

2 files

0.2.28

2 files

0.2.27

2 files

0.2.26

2 files

0.2.25

2 files

0.2.24

2 files

0.2.23

2 files

0.2.22

2 files

0.2.21

2 files

0.2.20

2 files

0.2.19

2 files

0.2.18

2 files

0.2.17

2 files

0.2.16

2 files

0.2.15

2 files

0.2.14

2 files

0.2.13

2 files

0.2.12

2 files

0.2.11

2 files

0.2.10

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.113

2 files

0.1.112

2 files

0.1.111

2 files

0.1.110

2 files

0.1.109

2 files

0.1.108

2 files

0.1.107

2 files

0.1.106

2 files

0.1.105

2 files

0.1.104

2 files

0.1.103

2 files

0.1.102

2 files

0.1.101

2 files

0.1.100

2 files

0.1.99

2 files

0.1.98

2 files

0.1.97

2 files

0.1.96

2 files

0.1.95

2 files

0.1.94

2 files

0.1.93

2 files

0.1.92

2 files

0.1.91

2 files

0.1.90

2 files

0.1.89

2 files

0.1.88

2 files

0.1.87

2 files

0.1.86

2 files

0.1.85

2 files

0.1.84

2 files

0.1.83

2 files

0.1.82

2 files

0.1.81

2 files

0.1.80

2 files

0.1.79

2 files

0.1.78

2 files

0.1.77

2 files

0.1.76

2 files

0.1.75

2 files

0.1.74

2 files

0.1.73

2 files

0.1.72

2 files

0.1.71

2 files

0.1.70

2 files

0.1.69

2 files

0.1.68

2 files

0.1.67

2 files

0.1.66

2 files

0.1.65

2 files

0.1.64

2 files

0.1.63

2 files

0.1.62

2 files

0.1.61

2 files

0.1.60

2 files

0.1.59

2 files

0.1.58

2 files

0.1.57

2 files

0.1.56

2 files

0.1.55

2 files

0.1.54

2 files

0.1.53

2 files

0.1.52

2 files

0.1.51

2 files

0.1.50

2 files

0.1.49

2 files

0.1.48

2 files

0.1.47

2 files

0.1.46

2 files

0.1.45

2 files

0.1.44

2 files

0.1.43

2 files

0.1.42

2 files

0.1.41

2 files

0.1.40

2 files

0.1.39

2 files

0.1.38

2 files

0.1.37

2 files

0.1.36

2 files

0.1.35

2 files

0.1.34

2 files

0.1.33

2 files

0.1.32

2 files

0.1.31

2 files

0.1.30

2 files

0.1.29

2 files

0.1.28

2 files

0.1.27

2 files

0.1.26

2 files

0.1.25

2 files

0.1.24

2 files

0.1.23

2 files

0.1.22

2 files

0.1.21

2 files

0.1.20

2 files

0.1.19

2 files

0.1.18

2 files

0.1.17

2 files

0.1.16

2 files

0.1.15

2 files

0.1.14

2 files

0.1.13

2 files

0.1.12

2 files

0.1.11

2 files

0.1.10

2 files

0.1.9

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page