fastrag.ingestion.steps.parsing.trafilatura#
Main-content extraction for arbitrary web pages, via Trafilatura.
HtmlParser removes page
furniture by CSS selector, which works when a site marks its chrome up with
<nav>/<footer> and fails on the many that build it out of anonymous
``div``s. DocusaurusParser
solves that for one site generator. This parser solves it heuristically for
any page: Trafilatura scores the DOM by text density and link ratio to find
the article, so no per-site selector is needed, at the price of the usual
heuristic risk of dropping a block a selector would have kept.
Module Attributes
Page metadata Trafilatura extracts that is carried into |
Classes
|
Extract a web page's main content as Markdown, with no per-site selectors. |
- fastrag.ingestion.steps.parsing.trafilatura.METADATA_FIELDS: tuple[str, ...] = ('title', 'author', 'date', 'description', 'sitename')#
Page metadata Trafilatura extracts that is carried into
Document.metadatawhen present, rather than into the embedded text.
- class fastrag.ingestion.steps.parsing.trafilatura.TrafilaturaParser(*, favor_precision=False, favor_recall=False, include_tables=True, include_links=True, include_images=False, include_comments=False, prune_xpath=(), encoding=None, cache=None, policy=None)[source]#
Bases:
ParserExtract a web page’s main content as Markdown, with no per-site selectors.
Trafilatura locates the article heuristically and discards navigation, sidebars, footers, and related-link blocks around it. Relative links are resolved against the source’s URI, and the page’s title, author, date, description, and site name travel in
Document.metadata.from fastrag.ingestion.steps.parsing import ( ParserRouter, TrafilaturaParser, html_filter, ) parser = ParserRouter(cache=cache).route( html_filter, TrafilaturaParser(favor_precision=True) )
- Parameters:
- content_format: ContentFormat = 'markdown'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- accepted_media_types: frozenset[str] | None = frozenset({'application/xhtml+xml', 'text/html'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- config()[source]#
This parser’s cache-identity configuration.
Every option changes what a given page’s bytes parse into, so all of them are part of the fingerprint.
- async transform(item, context)[source]#
Yield one Markdown document per page, or nothing if it has no content.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- effective_policy(context)#
Resolve this step’s policy over the one inherited from
context.The step’s own explicitly-set fields take priority; everything else falls through to the pipeline (or enclosing router/aggregator) policy.
- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
The stage this step’s work belongs to, e.g.
"Chunking".Declared as a plain class attribute by a family base class, and inherited by every concrete step in that family:
class Chunker(DocumentStep, ABC): event_name = "Chunking" class ChunkerRouter(RoutedStep[Document], Chunker): ... # -> "Chunking", inherited from `Chunker`
A concrete step overrides it to opt out of its family’s label:
class ChunkerRouter(RoutedStep[Document], Chunker): event_name = "ChunkerRouter" # -> "ChunkerRouter"
Resolution walks the MRO for the first class that declares it in its own class body (so a mixin listed first, e.g.
RoutedStep, contributes nothing unless it declares one itself), and falls back to the class’s own name when nothing in the MRO does — a step family that never declares anevent_namestill labels each of its steps distinctly rather than collapsing them under one blank heading. That fallback is computed per instance rather than assigned onto the class: assigning it would make it look “declared” to every subclass, which would then inherit their base’s name instead of getting their own.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- async run()#
Execute this step independently and collect every item.
Builds a default
ExecutionContextwhen none is installed (this step’s ownpolicy, or a freshPolicy). Intended primarily for testing and standalone use — pipeline-wide event observation isPipeline’s job.- Return type:
list[T]
- property upstream: PipelineStep[Any] | None#
Return the upstream step bound via
__call__, orNone.Read-only counterpart to
__call__’sself._upstreamassignment — lets external code (e.g.Pipeline, walking a graph from its root to classify each step by position) introspect composition without reaching into a private attribute.