Python
HTML
String Manipulation
Web Development
Data Cleaning

Strip HTML from strings in Python

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Removing HTML from text in Python seems easy until malformed markup, entities, scripts, and embedded styles appear in real data. The right approach depends on whether you only need plain text, safe user-visible HTML, or high-throughput preprocessing. Reliable stripping requires choosing parser-based tools over naive regex for most production workloads.

Choose the Right Tool for the Job

There are three common approaches:

  • regex stripping for simple trusted snippets
  • parser-based extraction for robust text cleanup
  • sanitization libraries when keeping safe HTML subset

If input comes from web pages or user-generated content, parser-based extraction is usually safest.

Fast Baseline With html.parser

Standard library approach with no external dependencies:

python
1from html.parser import HTMLParser
2
3class TextExtractor(HTMLParser):
4    def __init__(self):
5        super().__init__()
6        self.parts = []
7
8    def handle_data(self, data):
9        self.parts.append(data)
10
11    def get_text(self):
12        return " ".join(p.strip() for p in self.parts if p.strip())
13
14html = "<p>Hello <b>world</b> &amp; team</p>"
15parser = TextExtractor()
16parser.feed(html)
17print(parser.get_text())

This is a good default for moderate complexity inputs.

Robust Option With BeautifulSoup

For messy HTML and nested content, BeautifulSoup is often easier and more resilient.

python
1from bs4 import BeautifulSoup
2
3html = """
4<div>
5  <script>var x = 1;</script>
6  <p>Hello <b>world</b></p>
7</div>
8"""
9
10soup = BeautifulSoup(html, "html.parser")
11for tag in soup(["script", "style"]):
12    tag.decompose()
13
14text = soup.get_text(separator=" ", strip=True)
15print(text)

This handles malformed markup better than simple token stripping.

Why Regex Alone Is Risky

Regex can remove tags in trivial cases, but HTML is not a regular language and quickly breaks edge cases.

python
1import re
2
3html = "<p>Hello <b>world</b></p>"
4text = re.sub(r"<[^>]+>", "", html)
5print(text)

Use regex only for controlled and well-formed snippets, not arbitrary internet or user input.

Decode HTML Entities and Normalize Whitespace

After stripping tags, text may still contain entities and irregular whitespace.

python
1import html
2
3raw = "Hello&nbsp;&amp;&nbsp;welcome"
4decoded = html.unescape(raw)
5normalized = " ".join(decoded.split())
6print(normalized)

This step improves readability and downstream NLP consistency.

Pipeline Example for Data Cleaning

A practical reusable function:

python
1from bs4 import BeautifulSoup
2import html as html_lib
3
4
5def strip_html_text(value: str) -> str:
6    soup = BeautifulSoup(value, "html.parser")
7    for tag in soup(["script", "style"]):
8        tag.decompose()
9    text = soup.get_text(separator=" ", strip=True)
10    text = html_lib.unescape(text)
11    return " ".join(text.split())
12
13print(strip_html_text("<p>Hi&nbsp;<b>there</b></p>"))

Use the same function across ingestion paths so behavior remains consistent.

Security and Sanitization Distinction

Stripping HTML is not the same as sanitizing HTML for safe rendering. If output is rendered in browsers, use a sanitizer library to allow only safe tags and attributes.

For Python applications, bleach is often used when sanitized HTML output is required.

Example sanitizer flow:

python
1import bleach
2
3raw = "<p>Hello <b>world</b> <script>alert(1)</script></p>"
4safe_html = bleach.clean(raw, tags=["p", "b"], strip=True)
5print(safe_html)

Use this when output remains HTML, not plain text.

Throughput Considerations for Large Datasets

If you process millions of rows, parser choice and batching matter. Benchmark candidate approaches on representative samples, then standardize one method across jobs to keep output consistent. Mixed stripping logic across services is a common source of subtle data drift.

Common Pitfalls

  • Using regex for untrusted complex HTML and losing content incorrectly.
  • Forgetting to remove script and style blocks.
  • Ignoring HTML entity decoding after tag removal.
  • Mixing multiple strip methods with inconsistent output formats.
  • Assuming stripped text is safe for browser rendering without sanitization.

Summary

  • Prefer parser-based HTML stripping for real-world input.
  • Use standard parser or BeautifulSoup based on complexity.
  • Decode entities and normalize whitespace after tag removal.
  • Separate text extraction from HTML sanitization concerns.
  • Centralize stripping logic in one reusable function.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.