83 lines · 2.9 KB · Python
RawDownload
#!/usr/bin/env python3# -*- coding: utf-8 -*-# htmlAttributesExtract.py: extract all CSS classes, data-attribute keys, and IDs from HTML files# Author: Gwern Branwen# Date: 2022-09-10# When:  Time-stamp: "2025-11-27 22:59:06 gwern"# License: CC-0## BeautifulSoup utility to parse HTML & print all HTML classes, data-attribute keys, and IDs.# The usecase is to run over compiled corpus to extract all HTML classes and filter through a grep whitelist of known classes; this frequently catchs typos and unnecessary classes.# We check both classes & data-attribute keys for 'unknown' entries; we skip the data-attribute values because by design they will vary far too much to easily check.# (We use htmlAttributesExtract.py in `sync.sh`; the whitelist serves as additional documentation for Gwern.net features.)# We further extract IDs (prefixed with 'id:' to eliminate ambiguity) to allow checking for IDs which match whitelists/blacklists (eg. matching anything in the class or data-attribute whitelists, which is likely an error).## Usage: $ python htmlAttributesExtract.py file1.html file2.html ...## Examples:## $ python htmlAttributesExtract.py index.html# TOC# abstract smallcaps-not dropcap-not# ...# data-filesize-bytes# data-link-icon# ...# id:footnote-1# id:introduction# ... from bs4 import BeautifulSoupimport sysimport os # Validate argumentsif len(sys.argv) < 2:    print("Error: No input files provided.", file=sys.stderr)    print(f"Usage: $ {sys.argv[0]} file1.html [file2.html ...]", file=sys.stderr)    sys.exit(1) for filepath in sys.argv[1:]:    if not os.path.exists(filepath):        print(f"Error: File does not exist: {filepath}", file=sys.stderr)        sys.exit(1)    if not os.path.isfile(filepath):        print(f"Error: Not a regular file: {filepath}", file=sys.stderr)        sys.exit(1)    if not os.access(filepath, os.R_OK):        print(f"Error: File is not readable: {filepath}", file=sys.stderr)        sys.exit(1)    if os.path.getsize(filepath) == 0:        print(f"Error: File is empty: {filepath}", file=sys.stderr)        sys.exit(1) class_list = set()data_attr_list = set()id_list = set() for file_index in range(1, len(sys.argv)):    with open(sys.argv[file_index], "r") as f:        page = f.read()    soup = BeautifulSoup(page, 'html.parser')    # iterate all elements once    for element in soup.find_all():        if element.has_attr("class"):            class_list.add(" ".join(element['class']))        if element.has_attr("id"):            id_list.add(element['id'])        for attr in element.attrs:            if attr.startswith("data-"):                data_attr_list.add(attr) # print("Classes:")for val in sorted(class_list):    print(f"{val}") # print("\nData attributes:")for attr in sorted(data_attr_list):    print(f"{attr}") # print("\nIDs:")for id_val in sorted(id_list):    print(f"id:{id_val}") 

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t