Source code for ralph.mcp.webvisit.extractor
"""HTML text extraction for the visit_url tool.
Uses readability-lxml for main-content isolation and selectolax for fast
plain-text rendering. Both dependencies are included in the default ralph-workflow installation.
"""
from __future__ import annotations
from dataclasses import dataclass
from urllib.parse import urljoin, urlparse
from selectolax.parser import HTMLParser
from readability import Document
_MAX_LINKS = 100
def _collapse_whitespace(text: str) -> str:
lines = [line.strip() for line in text.splitlines()]
non_empty: list[str] = []
for line in lines:
if line or (non_empty and non_empty[-1]):
non_empty.append(line)
return "\n".join(non_empty).strip()
def _extract_links(html: str, *, base_url: str | None) -> tuple[str, ...]:
parser = HTMLParser(html)
seen: set[str] = set()
result: list[str] = []
for node in parser.css("a[href]"):
href = (node.attributes.get("href") or "").strip()
if not href or href.startswith(("#", "javascript:", "mailto:", "tel:")):
continue
absolute = urljoin(base_url or "", href) if base_url else href
parsed = urlparse(absolute)
if parsed.scheme not in {"http", "https"}:
continue
if absolute not in seen:
seen.add(absolute)
result.append(absolute)
if len(result) >= _MAX_LINKS:
break
return tuple(result)
__all__ = ["ExtractedPage", "extract_readable"]