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.107.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.107-py3-none-any.whl (832.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: matrx_scraper-0.2.107.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.107.tar.gz
Algorithm Hash digest
SHA256 faedf363cef9838505cc7769efeb117bf26be35390c609a9a37c4671b3edbd71
MD5 86b69a778bb36e7e19cb781a7c162bf8
BLAKE2b-256 d220d60c88656afc0db61c036aa643893d0fc9678e285de596039745f7662c79

See more details on using hashes here.

Provenance

The following attestation bundles were made for matrx_scraper-0.2.107.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.107-py3-none-any.whl.

File metadata

  • Download URL: matrx_scraper-0.2.107-py3-none-any.whl
  • Upload date:
  • Size: 832.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.107-py3-none-any.whl
Algorithm Hash digest
SHA256 80ce6b7923eaf25fd9184793f2b11f932ae111a2526beb133a99a7b100d02048
MD5 bc7565ea1ccafe75c6ade4333a2a0f4b
BLAKE2b-256 e99ec019bb293c7198587108a641bac4506f8129b6e1f26dab0163590496e611

See more details on using hashes here.

Provenance

The following attestation bundles were made for matrx_scraper-0.2.107-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

0.2.110

2 files

0.2.109

2 files

0.2.108

2 files

This release

0.2.107 This release

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