Collect text from selected HTML tags with HTMLParser
HTMLParser is useful when a small task needs parser callbacks rather than a CSS-selector engine. This example selects only h2 and p elements from a fixed HTML fragment. handle_starttag() records a new text buffer for a selected tag, handle_data() appends text while that buffer is active, and handle_endtag() finalizes the collected value. The assertions check both selection and encounter order: the aside text must not appear, while the nested em text remains part of its surrounding paragraph.
The printed list is therefore ['Setup', 'Use a parser.']. HTMLParser lowercases tag names before delivering them to handle_starttag(), so the selected tag set is written in lowercase. With its default convert_charrefs=True, ordinary character references are converted before data is delivered; this example does not rely on that behavior.
This is deliberately a small callback-based collector, not a complete document model. HTMLParser accepts malformed HTML, but it does not verify matching end tags or infer every implicit close, so a production extractor may need explicit rules for the HTML it accepts. It also collects textual data as delivered by callbacks and does not create whitespace between adjacent fragments automatically.
The documented callback and feed() behavior are described in the Python html.parser documentation.
AI assistance disclosure: AI helped draft this educational example; its assertions should still be run in the target environment.
from html.parser import HTMLParser
class SelectedText(HTMLParser):
def __init__(self, tags):
super().__init__()
self.tags = set(tags)
self.active = []
self.values = []
def handle_starttag(self, tag, attrs):
if tag in self.tags:
self.active.append((tag, []))
def handle_data(self, data):
if self.active:
self.active[-1][1].append(data)
def handle_endtag(self, tag):
if self.active and self.active[-1][0] == tag:
_, parts = self.active.pop()
self.values.append("".join(parts).strip())
parser = SelectedText({"h2", "p"})
parser.feed("<h2>Setup</h2><aside>Skip me</aside><p>Use <em>a parser</em>.</p>")
parser.close()
assert parser.values == ["Setup", "Use a parser."]
print(parser.values)
['Setup', 'Use a parser.']
Comments
Post a Comment