Small, dependable HTML cleaner/minifier with sensible defaults
Project description
smol-html
Small, dependable HTML cleaner/minifier with sensible defaults.
Motivation
Nosible is a search engine, which means we need to store and process a very large number of webpages. To make this tractable, we strip out visual chrome and other non-essential components that don’t matter for downstream tasks (indexing, ranking, retrieval, and LLM pipelines) while preserving the important content and structure. This package cleans and minifies HTML, greatly reducing size on disk; combined with Brotli compression (by Google), the savings are even larger.
📦 Installation
pip install smol-html
⚡ Installing with uv
uv pip install smol-html
Requirements
- Python: 3.9
- Dependencies:
- beautifulsoup4>=4.0.1
- brotli>=0.5.2
- lxml[html-clean]>=1.3.2
- minify-html>=0.2.6
Quick Start
Clean an HTML string (or page contents):
from smol_html import SmolHtmlCleaner
html = """
<html>
<head><title> Example </title></head>
<body>
<div> Hello <span> world </span> </div>
</body>
</html>
"""
# All constructor arguments are keyword-only and optional.
cleaner = SmolHtmlCleaner()
cleaned = cleaner.make_smol(raw_html=html)
print(cleaned)
Customization
SmolHtmlCleaner exposes keyword-only parameters with practical defaults. You can:
- Pass overrides to the constructor, or
- Adjust attributes on the instance after creation.
from smol_html import SmolHtmlCleaner
cleaner = SmolHtmlCleaner()
cleaner.attr_stop_words.add("advert") # e.g., add a custom stop word
Usage Examples
Minimal:
from smol_html import SmolHtmlCleaner
cleaner = SmolHtmlCleaner()
out = cleaner.make_smol(raw_html="<p>Hi <!-- note --> <a href='x'>link</a></p>")
Customize a few options:
from smol_html import SmolHtmlCleaner
cleaner = SmolHtmlCleaner(
attr_stop_words={"nav", "advert"},
remove_header_lists=False,
minify=True,
)
out = cleaner.make_smol(raw_html="<p>Hi</p>")
Compressed Bytes Output
Produce compressed bytes using Brotli with make_smol_bytes
from smol_html import SmolHtmlCleaner
import brotli # only needed if you want to decompress here in the example
html = """
<html>
<body>
<div> Hello <span> world </span> </div>
</body>
</html>
"""
cleaner = SmolHtmlCleaner()
# Get compressed bytes (quality 11 is strong compression)
compressed = cleaner.make_smol_bytes(raw_html=html, compression_level=11)
# Example: decompress back to text to inspect (optional)
decompressed = brotli.decompress(compressed).decode("utf-8")
print(decompressed)
# Or write compressed output directly to a file
with open("page.html.br", "wb") as f:
f.write(compressed)
Parameter Reference
To improve readability, the reference is split into two tables:
- What it does and when to change
- Types and default values
What It Does
| Parameter | What it does | When to change |
|---|---|---|
non_text_to_keep |
Whitelist of empty/non-text tags to preserve (e.g., images, figures, tables, line breaks). | If important non-text elements are being removed or you want to keep/drop more empty tags. |
attr_stop_words |
Tokens matched against id/class/role/item_type on small elements; matches are removed as likely non-content. |
Add tokens like advert, hero, menu to aggressively drop UI chrome, or remove tokens if content is lost. |
remove_header_lists |
Removes links/lists/images within <header> to reduce nav clutter. |
Set False if your header contains meaningful content you want to keep. |
remove_footer_lists |
Removes links/lists/images within <footer> to reduce boilerplate. |
Set False for content-heavy footers you need. |
minify |
Minifies output HTML using minify_html. |
Set False for readability or debugging; use --pretty in the CLI. |
minify_kwargs |
Extra options passed to minify_html.minify. |
Tune minification behavior (e.g., whitespace, comments) without changing cleaning. |
meta |
lxml Cleaner option: remove <meta> content when True. |
Usually leave False; enable only for strict sanitation. |
page_structure |
lxml Cleaner option: remove page-structure tags (e.g., <head>, <body>) when True. |
Rarely needed; keep False to preserve structure. |
links |
lxml Cleaner option: sanitize/clean links. | Leave True unless you need raw anchors untouched. |
scripts |
lxml Cleaner option: remove <script> tags when True. |
Keep False to preserve scripts; usually safe to remove via javascript=True anyway. |
javascript |
lxml Cleaner option: remove JS and event handlers. | Set False only if you truly need inline JS (not recommended). |
comments |
lxml Cleaner option: remove HTML comments. | Set False to retain comments for debugging. |
style |
lxml Cleaner option: remove CSS and style attributes. | Set False to keep inline styles/CSS. |
processing_instructions |
lxml Cleaner option: remove processing instructions. | Rarely change; keep for safety. |
embedded |
lxml Cleaner option: remove embedded content (e.g., <embed>, <object>). |
Set False to keep embedded media. |
frames |
lxml Cleaner option: remove frames/iframes. | Set False if iframes contain needed content. |
forms |
lxml Cleaner option: remove form elements. | Set False if you need to keep forms/inputs. |
annoying_tags |
lxml Cleaner option: remove tags considered "annoying" by lxml (e.g., <blink>, <marquee>). |
Rarely change. |
kill_tags |
Additional explicit tags to remove entirely. | Add site-specific or custom tags to drop. |
remove_unknown_tags |
lxml Cleaner option: drop unknown/invalid tags. | Set False if you rely on custom elements. |
safe_attrs_only |
Only allow attributes listed in safe_attrs. |
Set False if you need to keep arbitrary attributes. |
safe_attrs |
Allowed HTML attributes when safe_attrs_only=True. |
Extend to keep additional attributes you trust. |
Types and Defaults
| Parameter | Type | Default |
|---|---|---|
non_text_to_keep |
set[str] |
media/meta/table/br tags |
attr_stop_words |
set[str] |
common UI/navigation tokens |
remove_header_lists |
bool |
True |
remove_footer_lists |
bool |
True |
minify |
bool |
True |
minify_kwargs |
dict |
{} |
meta |
bool |
False |
page_structure |
bool |
False |
links |
bool |
True |
scripts |
bool |
False |
javascript |
bool |
True |
comments |
bool |
True |
style |
bool |
True |
processing_instructions |
bool |
True |
embedded |
bool |
True |
frames |
bool |
True |
forms |
bool |
True |
annoying_tags |
bool |
True |
kill_tags |
set[str] | None |
None |
remove_unknown_tags |
bool |
True |
safe_attrs_only |
bool |
True |
safe_attrs |
set[str] |
curated set |
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smol_html-0.1.4.tar.gz.
File metadata
- Download URL: smol_html-0.1.4.tar.gz
- Upload date:
- Size: 2.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2fbf78d09a89021330cb9669d41d11223c1eb3f61973bf91f78b2e48e631d3df
|
|
| MD5 |
0db1648f5ea1726baf05839e818129a6
|
|
| BLAKE2b-256 |
6d415fcb1171de35c5b9aab2ebc64c4bc2a281da99549925302d2466345d4d86
|
File details
Details for the file smol_html-0.1.4-py3-none-any.whl.
File metadata
- Download URL: smol_html-0.1.4-py3-none-any.whl
- Upload date:
- Size: 4.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
915f858f3b4d32db6b3bef49ef6f56b7ef04059ec2605c58acce43229ca585ab
|
|
| MD5 |
f992148b8d9c3ca9789e69b9beb01584
|
|
| BLAKE2b-256 |
29c9d88a4d72b7e400734d52f98c63a8993a3f2b8e4e47fdb96ddbacb7724f81
|