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 ¶
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 ¶
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 ¶
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 ¶
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 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.
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 ¶
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.