Skip to main content

HTMLStream is a simple stream parser for HTML. Rather than load an entire DOM into memory all at once, HTMLStream reads a io stream incrementally, resulting in a stream of HTML tags and text. The aim is to be fairly permissible, generating usable results from even malformed HTML.

Installing

With pip:

$ pip install fa-htmlstream

Examples

Find the doc type of a document:

from htmlstream import Parser, DocType, Text

def getDocType(filename:str) -> str:
    with open(filename, encoding='utf-8') as file:
        for node in Parser(file):
            if isinstance(node, Text): continue

            if isinstance(node, DocType):
                return node.doctype
            else:
                raise Exception('No doctype!')

Extract all the text:

from htmlstream import Parser, Text

def getAllText(filename:str) -> str:
    text = ''

    with open(filename, encoding='utf-8') as file:
        for node in Parser(file):
            if isinstance(node, Text):
                text += node.text

    return text

Get the text of a specific element:

from htmlstream import Parser, OpenTag, Text

def getElementText(filename:str, eid:str) -> str:
    inElement = False
    with open(filename, encoding='utf-8') as file:
        for node in Parser(file):
            if inElement and isinstance(node, Text):
                return node.text
            if isinstance(node, OpenTag) and node.attributes.get('id') == eid):
                inElement = True

    return 'MISSING'

The Cursor

We can simplify some of the above using the Cursor wrapper class. The Cursor has additional state to keep track of where it is in the element hierarchy and provide utility operations.

For example, get the text of a specific element becomes:

from htmlstream import Parser, Cursor

def getElementText(filename:str, eid:str) -> str:
    with open(filename, encoding='utf-8') as file:
        html = Cursor(Parser(file))
        if not html.findOpenTag('', {'id': eid}):
            return 'MISSING'
        return html.getInnerText()

API

class Parser(Iterator[Node])

The parser itself. The parser is an iterator, so it can be used if for loops, passed to list() and next(), and used in list comprehensions.

__init__(stream: TextIOBase, maxTextLength: int|None = None)
stream:

The text stream to parse (e.g. a file object).

maxTextLength:

The maximum length of a text node; unlimited if None

__next__() -> Node

Get the next node in the stream.

__iter__() -> Iterator[Node]

The Parser itself.

class Node

Base node class.

class Text(Node)

A text node. This includes any and all text between tags, comments, and doctypes.

text str:

The content of the section of text.

class Comment(Node)

A comment node. All the text between the opening <!– and closing –>.

comment str:

The content of the comment.

class DocType(Node)

A doctype node.

doctype str:

The specific doctype declared (i.e. “html”).

class Tag(Node)

Base tag class.

tag str:

The name of the tag (e.g. “p”, “table”, “body”, etc.).

class OpenTag(Tag)

An opening tag, including unclosed and self-closing tags.

selfClosing bool:

True if the tag is self-closing (for example <br />).

attributes dict[str,str|None]:

The attributes included in tag. Toggle attributes have the value None.

__getitem__(attr:str) -> str|None

Get the value of an attribute. Returns None for toggle attributes. :attr: The name of the attribute

__contains__(attr:str) -> str|None

Returns true if the specified attribute is set on the tag. :attr: The name of the attribute

class CloseTag(Tag)

A closing tag.

class Cursor(Iterator[Node])

A utility class that wraps a Parser, providing additional tree-streaming functionality. The Cursor moves through the Parser’s node stream linearly, effectively processing the HTML tree in a depth-first manner.

stack list[OpenTag]:

The current heirarchy of tags, where stack[0] is the root element of of the document (e.g. <html), and stack[-1] is the opening tag of the element the cursor is currently inside of.

depth int:

The number of elements deep into the tree the curser is.

__init__(parser: Parser)
parser:

The Parser to wrap.

__next__() -> Node

Get the next node in the stream.

__iter__() -> Iterator[Node]

The Cursor itself.

findOpenTag(tag: str, attrs: dict[str, str]|None = None) -> Node|None

Move the cursor the next matching open tag. Returns the tag (or None, if the exact tag couldn’t be found). :tag: The tag name to search for (e.g. “body” or “img”). If empty, matches any tag. :attr: Optional specific attributes the tag must have

getInnerText() -> str

Get the text of all of the text nodes within the current element.

getInnerHtml() -> str

Get the html within the current element.

Metadata

Release files for fa-htmlstream 1.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fa-htmlstream 1.2.1
File Size Uploaded
fa_htmlstream-1.2.1.tar.gz 17.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fa-htmlstream 1.2.1
File Interpreter ABI Platform
fa_htmlstream-1.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 33.2 kB

Release files / fa_htmlstream-1.2.1.tar.gz

Download URL fa_htmlstream-1.2.1.tar.gz
Size 17.1 kB
Tags Source
SHA-256 checksum
How to use checksums
4da9f0378f13d84ab176f8b2a06701a35483de227980fe696f0c7e14f89101b8
BLAKE2b-256 checksum
How to use checksums
71fb0860d7e47211dde1f73c004c0aaad4aa3f8e79aad72576e6e597c908e00c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 16, 2025.

Transparency log

Release files / fa_htmlstream-1.2.1-py3-none-any.whl

Download URL fa_htmlstream-1.2.1-py3-none-any.whl
Size 16.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6ba03061d676e393a9832c0dd1a7fb30dcbfcd6322c789a97a99b15f9f3ee806
BLAKE2b-256 checksum
How to use checksums
41034ba61d6c801fca42743130f01f498667585915cde6c79a1e103114b0bf82
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 16, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.1 This release

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page