extractors

package
v0.0.0-...-a7c30c4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package extractors holds the pure, DOM-in/data-out functions that recover an article's body, metadata, and media from a parsed page. Nothing here touches the network or imports the root package, which keeps the algorithms unit- testable on fixture HTML and free of import cycles.

The body extractors come in two flavours that share the block model in this file:

  • Density (density.go): the newspaper3k/goose stopword-density heuristic.
  • HMM (hmm.go): a train-free hidden Markov model decoded with Viterbi that adds a "content is contiguous" prior.

Both ultimately rank DOM text by stopword density (see the stopwords package), which is the cheap, language-agnostic signal that prose is dense with common words while boilerplate is not.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NormalizeWS

func NormalizeWS(s string) string

NormalizeWS collapses runs of whitespace into single spaces and trims the result. Used everywhere we emit human-facing text.

Types

type Block

type Block struct {
	Sel       *goquery.Selection
	Text      string
	Tag       string
	WordCount int
	Stopwords int
	LinkWords int
}

Block is one text-bearing element in document order, pre-measured with the features every body extractor needs. The HMM treats the slice of Blocks as a sequence of observations; helpers here are also reused by the density heuristic.

func Segment

func Segment(doc *goquery.Document, set *stopwords.Set) []Block

Segment walks doc and returns the candidate text blocks in document order, each measured against the given stopword set. Empty blocks are skipped.

func (Block) LinkDensity

func (b Block) LinkDensity() float64

LinkDensity is the fraction of the block's words that sit inside <a> tags — high for navigation/link lists, low for prose.

func (Block) StopwordRatio

func (b Block) StopwordRatio() float64

StopwordRatio is the fraction of the block's words that are stopwords — the primary "is this prose?" signal.

type HMMParams

type HMMParams struct {
	// InitContent is the prior probability the first block is content. Pages
	// typically open with nav/boilerplate, so this is low.
	InitContent float64
	// TransCC / TransBB are the self-transition probabilities. High values make
	// each state sticky, which is what enforces a contiguous content run.
	TransCC float64
	TransBB float64

	// Emission weights map a block's features to a "contentness" score.
	StopwordPivot  float64 // stopword ratio considered neutral
	StopwordWeight float64 // pull from stopword density
	LengthWeight   float64 // pull from block length
	LinkWeight     float64 // push from link density
}

HMMParams holds the (hand-tuned) probabilities and emission weights.

func DefaultHMMParams

func DefaultHMMParams() HMMParams

DefaultHMMParams returns sensible, hand-tuned defaults.

type Media

type Media struct {
	TopImage string
	Images   []string
	Movies   []string
}

Media holds discovered media URLs (resolved to absolute form).

func ExtractMedia

func ExtractMedia(doc *goquery.Document, body *goquery.Selection, pageURL string) Media

ExtractMedia finds the lead image and other media. body is the extracted article subtree (may be nil) and is preferred when falling back to the largest in-article image. See docs/metadata.md.

type Meta

type Meta struct {
	Title        string
	Authors      []string
	PublishDate  time.Time
	Description  string
	MetaKeywords []string
	Language     string
	Canonical    string
	Favicon      string
	SiteName     string
	Tags         []string
}

Meta is the structured, non-body information recovered from a page. The root package translates this into its public Metadata type.

func ExtractMetadata

func ExtractMetadata(doc *goquery.Document, pageURL string) Meta

ExtractMetadata recovers structured fields from doc. For each field it tries sources from most reliable to least and takes the first hit — see docs/metadata.md. pageURL resolves relative links.

type Options

type Options struct {
	// MinWordCount is the caption/cruft cutoff used while cleaning the body.
	MinWordCount int
	// MinSentenceLength (in words) below which a fragment is treated as a label.
	MinSentenceLength int
}

Options tunes extraction. It mirrors the relevant Config fields but keeps this package independent of the root package.

type Result

type Result struct {
	// Text is the cleaned article body.
	Text string
	// TopNode is the DOM subtree the body came from, when the strategy can
	// identify one (the density heuristic can; the HMM works on a flat block
	// sequence and may leave this nil).
	TopNode *goquery.Selection
}

Result is the output of a body extractor.

func Density

func Density(doc *goquery.Document, set *stopwords.Set, opts Options) Result

Density implements the newspaper3k/goose content-extraction heuristic.

The idea (see docs/extraction.md): score every text node by its stopword count, then bubble each node's score up to its parent and (half) to its grandparent. The container that accumulates the most "prose weight" from its children is the article body. We then clean that subtree and emit its text.

This is faithful to the original algorithm, including its positional boost (rewarding early paragraphs) and end-of-article penalty.

func HMM

func HMM(doc *goquery.Document, set *stopwords.Set, params HMMParams, opts Options) Result

HMM extracts the article body by Viterbi-decoding the block sequence.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址