Skip to main content

web2textpy

Python reimplementation of the Web2Text pipeline for labeling HTML DOM nodes as content or boilerplate using paired (raw_html, clean_text) data.

Installation

uv add web2textpy

Quick Start

from datasets import load_dataset
from web2text import run_pipeline

ds = load_dataset("williambrach/html-boilerplate-labeled", split="test")
row = ds[0]

tree, extracted_text, metrics = run_pipeline(row["html"], row["text"])

print(extracted_text[:200])
print(metrics)

Get text from labeled HTML

from web2text import extract_text_from_labeled_html
text = extract_text_from_labeled_html(labeled_html_string)

Step-by-Step API

Each stage of the pipeline is exposed as a standalone function:

from web2text import build_cdom, extract_leaves, align, label_nodes, extract_text, evaluate

# 1. Parse HTML into a collapsed DOM tree
tree = build_cdom(html_string)

# 2. Extract ordered text-bearing leaf nodes
leaves = extract_leaves(tree)  # [(element, "normalized text"), ...]

# 3. Align leaf texts against ground-truth clean text
scores = align(leaves, clean_text)  # {leaf_id: 0.0-1.0 match score}

# 4. Label each node as "content" or "boilerplate"
tree = label_nodes(tree, scores, threshold=0.667)

# 5. Extract text from content-labeled nodes
result = extract_text(tree)

# 6. Evaluate against ground truth
metrics = evaluate(result, clean_text)
# => {'token_f1': 0.99, 'precision': 0.99, 'recall': 0.99, 'rouge1_f': 0.99, 'bleu': 98.5, 'chrf': 98.8}

How the Matching Algorithm Works

Given raw HTML and its known clean text, the algorithm determines which DOM nodes are content versus boilerplate in six steps:

  1. Simplify the DOM — strip non-content tags (<script>, <style>, etc.) and collapse single-child chains into a Collapsed DOM (CDOM) representation
  2. Collect leaf text — walk the CDOM, concatenate text from every leaf node into one source string with tracked character offsets
  3. Find anchors — identify 10-character substrings that appear exactly once in both the source and clean text, splitting the problem into independent segments
  4. DP alignment — for each segment between anchors, run character-level dynamic programming with affine gap penalties to map source characters to clean-text characters
  5. Score leaves — map alignment results back to leaf boundaries via stored offsets, giving each leaf a score: matched_chars / total_chars
  6. Label nodes — leaves scoring above 0.667 are labeled "content", the rest "boilerplate", with labels propagating upward to parents

Alignment pipeline: extract leaf texts → anchor matching → DP alignment → per-leaf scores

Dataset

Dataset: williambrach/html-boilerplate-labeled — ~4k pages from CleanEval, Dragnet, CETD, Readability, and others (3,985 pages total).

Source Train (ROUGE-1 F) Test (ROUGE-1 F)
readability 0.993 (92) 0.997 (23)
scrapinghub 0.991 (145) 0.996 (36)
cetd 0.993 (560) 0.987 (140)
google-trends-2017 0.986 (144) 0.995 (36)
cleanportaleval 0.985 (57) 0.971 (14)
cleaneval 0.985 (590) 0.991 (148)
dragnet 0.983 (1,103) 0.983 (276)
l3s-gn1 0.920 (497) 0.927 (124)
Overall 0.976 (3,188) 0.978 (797)

Sample counts in parentheses.

Original Work

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

web2textpy-0.2.1.tar.gz (158.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

web2textpy-0.2.1-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

File details

Details for the file web2textpy-0.2.1.tar.gz.

File metadata

  • Download URL: web2textpy-0.2.1.tar.gz
  • Upload date:
  • Size: 158.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.16

File hashes

Hashes for web2textpy-0.2.1.tar.gz
Algorithm Hash digest
SHA256 aac70309f8cb7328ed335b86a0eea9a666416d2fdd723732e4f9c7545f67a938
MD5 653f47b23fb82334f5abea7a4d2e20f7
BLAKE2b-256 3ce3f230ab891bf4182467bc5aa7fa1144b6c6710bd7ce56f6f96bd46ccd53b7

See more details on using hashes here.

File details

Details for the file web2textpy-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: web2textpy-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 15.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.16

File hashes

Hashes for web2textpy-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2cb7c2bda581acad264724878ed97087c2b76c7572b2275b937458aff2056b8a
MD5 3cda536069bcc43d7673666d77c6d781
BLAKE2b-256 d7fbb735c7a3cb3190557ecbb43fa58fe235e991e0c5f86750eb587d9d4f3e07

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 files

0.2.0

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