HTML Cleaner

Paste messy HTML, get clean text back.

Welcome to another official UVF IT build session. Today we are creating a minimal, server-side clone of 'Jack the Snipper', a tool designed to strip HTML tags and formatting from pasted content, leaving you with clean, readable plain text.

This project uses Python and Flask to handle the heavy lifting of HTML sanitization. You will learn how to accept user input, process it using a robust library like bleach, and return a sanitized result, all within a simple, self-contained application.

Prerequisites & Simplifications

Application Architecture
LOCAL RUNTIME POST /clean Process HTML Sanitized String Return Result Browser User Input Flask App Python Server Bleach Lib HTML Sanitizer Clean Text JSON Response
1

Phase 1: Scaffold the Project

Create a new directory for your project and initialize a virtual environment to keep dependencies isolated. This is the standard practice for Python web apps, ensuring your system Python remains clean and your project dependencies are version-controlled.

mkdir html-cleaner-clone
cd html-cleaner-clone
python3 -m venv venv
source venv/bin/activate
2

Phase 2: Install Dependencies

We need Flask for the web server and bleach for cleaning the HTML. bleach is a trusted library that removes unwanted tags and attributes while preserving safe text, making it perfect for this sanitization task.

pip install flask bleach
3

Phase 3: Build the Core Logic

Create the main application file. We will define a single endpoint /clean that accepts a POST request with JSON data containing the 'html' field. The bleach.clean function will strip all tags, leaving only plain text.

We configure bleach to allow no tags (tags=[]) and no attributes (attributes={}), ensuring that even inline styles or scripts are completely removed. This creates a strict plain-text output from any messy HTML input.

app.py

from flask import Flask, request, jsonify
import bleach

app = Flask(__name__)

@app.route('/clean', methods=['POST'])
def clean_html():
    data = request.get_json()
    if not data or 'html' not in data:
        return jsonify({'error': 'No HTML provided'}), 400
    
    raw_html = data['html']
    # Strip all tags and attributes to get plain text
    clean_text = bleach.clean(raw_html, tags=[], attributes={}, strip=True)
    
    return jsonify({'clean_text': clean_text})

if __name__ == '__main__':
    app.run(debug=True)
4

Phase 4: Create a Simple UI

Create an templates folder and an index.html file. This simple HTML page will contain a textarea for input and a button to send the data to our API. We use vanilla JavaScript to handle the fetch request.

The frontend is kept minimal to focus on the core functionality. We use a standard POST request to send the HTML content to the /clean endpoint we defined earlier. The response is then displayed in a result div.

We include basic error handling in the JavaScript to ensure the user is notified if the server fails to respond. This makes the application more robust and user-friendly.

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTML Cleaner</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        textarea {
            width: 100%;
            height: 150px;
            margin-bottom: 10px;
        }
        button {
            padding: 10px 20px;
            background-color: #007bff;
            color: white;
            border: none;
            cursor: pointer;
        }
        button:hover {
            background-color: #0056b3;
        }
        #result {
            margin-top: 20px;
            padding: 10px;
            background-color: #f8f9fa;
            border: 1px solid #dee2e6;
            white-space: pre-wrap;
        }
    </style>
</head>
<body>
    <h1>HTML Cleaner</h1>
    <textarea id="htmlInput" placeholder="Paste your HTML here..."></textarea>
    <button onclick="cleanHtml()">Clean Text</button>
    <div id="result"></div>

    <script>
        async function cleanHtml() {
            const htmlContent = document.getElementById('htmlInput').value;
            const resultDiv = document.getElementById('result');
            
            try {
                const response = await fetch('/clean', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ html: htmlContent })
                });
                
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                
                const data = await response.json();
                resultDiv.textContent = data.clean_text;
            } catch (error) {
                resultDiv.textContent = 'Error: ' + error.message;
            }
        }
    </script>
</body>
</html>
5

Phase 5: Run and Verify

Update app.py to serve the index page on the root route, then run the application. Open your browser to localhost:5000 to test the tool.

We add a simple route for the root URL that renders the index.html template. This allows users to access the UI directly by visiting the base URL of the application.

Finally, we run the Flask development server. This will start the application locally, and you can interact with it through your web browser to verify that the HTML cleaning functionality works as expected.

app.py

from flask import Flask, request, jsonify, render_template
import bleach

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/clean', methods=['POST'])
def clean_html():
    data = request.get_json()
    if not data or 'html' not in data:
        return jsonify({'error': 'No HTML content provided'}), 400
    
    html_content = data['html']
    # Strip all tags, leaving only plain text
    clean_text = bleach.clean(html_content, tags=[], attributes={}, strip=True)
    
    return jsonify({'clean_text': clean_text})

if __name__ == '__main__':
    app.run(debug=True)

Verifying the Stack

CheckCommand / Why it matters
Server starts without errorsRun python app.py and see 'Running on http://127.0.0.1:5000' in the terminal.
UI loads correctlyOpen http://localhost:5000 in your browser; you should see the textarea and button.
HTML is strippedPaste <p>Hello <b>World</b></p> into the textarea, click 'Clean Text', and verify the result is Hello World.

Next Steps

You now have a working HTML cleaner. Try extending it by adding options to preserve specific tags like <a> or <img>, or by adding a 'Copy to Clipboard' button for better UX.