:mod:`!html.parser` --- Simple HTML and XHTML parser
====================================================

.. module:: html.parser
   :synopsis: A simple parser that can handle HTML and XHTML.

**Source code:** :source:`Lib/html/parser.py`

.. index::
   single: HTML
   single: XHTML

--------------

This module defines a class :class:`HTMLParser` which serves as the basis for
parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML.

.. class:: HTMLParser(*, convert_charrefs=True, scripting=False)

   Create a parser instance able to parse invalid markup.

   If *convert_charrefs* is true (the default), all character
   references (except the ones in elements like ``script`` and ``style``) are
   automatically converted to the corresponding Unicode characters.

   If *scripting* is false (the default), the content of the ``noscript``
   element is parsed normally; if it's true, it's returned as is without
   being parsed.

   An :class:`.HTMLParser` instance is fed HTML data and calls handler methods
   when start tags, end tags, text, comments, and other markup elements are
   encountered.  The user should subclass :class:`.HTMLParser` and override its
   methods to implement the desired behavior.

   This parser does not check that end tags match start tags or call the end-tag
   handler for elements which are closed implicitly by closing an outer element.

   .. versionchanged:: 3.4
      *convert_charrefs* keyword argument added.

   .. versionchanged:: 3.5
      The default value for argument *convert_charrefs* is now ``True``.

   .. versionchanged:: 3.14.1
      Added the *scripting* parameter.


Example HTML Parser Application
-------------------------------

As a basic example, below is a simple HTML parser that uses the
:class:`HTMLParser` class to print out start tags, end tags, and data
as they are encountered:

.. testcode::

   from html.parser import HTMLParser

   class MyHTMLParser(HTMLParser):
       def handle_starttag(self, tag, attrs):
           print("Encountered a start tag:", tag)

       def handle_endtag(self, tag):
           print("Encountered an end tag :", tag)

       def handle_data(self, data):
           print("Encountered some data  :", data)

   parser = MyHTMLParser()
   parser.feed('<html><head><title>Test</title></head>'
               '<body><h1>Parse me!</h1></body></html>')

The output will then be:

.. testoutput::

   Encountered a start tag: html
   Encountered a start tag: head
   Encountered a start tag: title
   Encountered some data  : Test
   Encountered an end tag : title
   Encountered an end tag : head
   Encountered a start tag: body
   Encountered a start tag: h1
   Encountered some data  : Parse me!
   Encountered an end tag : h1
   Encountered an end tag : body
   Encountered an end tag : html


:class:`.HTMLParser` Methods
----------------------------

:class:`HTMLParser` instances have the following methods:


.. method:: HTMLParser.feed(data)

   Feed some text to the parser.  It is processed insofar as it consists of
   complete elements; incomplete data is buffered until more data is fed or
   :meth:`close` is called.  *data* must be :class:`str`.


.. method:: HTMLParser.close()

   Force processing of all buffered data as if it were followed by an end-of-file
   mark.  This method may be redefined by a derived class to define additional
   processing at the end of the input, but the redefined version should always call
   the :class:`HTMLParser` base class method :meth:`close`.


.. method:: HTMLParser.reset()

   Reset the instance.  Loses all unprocessed data.  This is called implicitly at
   instantiation time.


.. method:: HTMLParser.getpos()

   Return current line number and offset.


.. method:: HTMLParser.get_starttag_text()

   Return the text of the most recently opened start tag.  This should not normally
   be needed for structured processing, but may be useful in dealing with HTML "as
   deployed" or for re-generating input with minimal changes (whitespace between
   attributes can be preserved, etc.).


The following methods are called when data or markup elements are encountered
and they are meant to be overridden in a subclass.  The base class
implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`):


.. method:: HTMLParser.handle_starttag(tag, attrs)

   This method is called to handle the start tag of an element (e.g. ``<div id="main">``).

   The *tag* argument is the name of the tag converted to lower case. The *attrs*
   argument is a list of ``(name, value)`` pairs containing the attributes found
   inside the tag's ``<>`` brackets.  The *name* will be translated to lower case,
   and quotes in the *value* have been removed, and character and entity references
   have been replaced.  For empty attributes, *value* is ``None``.

   For instance, for the tag ``<A HREF="https://www.cwi.nl/">``, this method
   would be called as ``handle_starttag('a', [('href', 'https://www.cwi.nl/')])``.

   All entity references from :mod:`html.entities` are replaced in the attribute
   values.


.. method:: HTMLParser.handle_endtag(tag)

   This method is called to handle the end tag of an element (e.g. ``</div>``).

   The *tag* argument is the name of the tag converted to lower case.


.. method:: HTMLParser.handle_startendtag(tag, attrs)

   Similar to :meth:`handle_starttag`, but called when the parser encounters an
   XHTML-style empty tag (``<img ... />``).  This method may be overridden by
   subclasses which require this particular lexical information; the default
   implementation simply calls :meth:`handle_starttag` and :meth:`handle_endtag`.


.. method:: HTMLParser.handle_data(data)

   This method is called to process arbitrary data (e.g. text nodes and the
   content of elements like ``script`` and ``style``).


.. method:: HTMLParser.handle_entityref(name)

   This method is called to process a named character reference of the form
   ``&name;`` (e.g. ``&gt;``), where *name* is a general entity reference
   (e.g. ``'gt'``).
   This method is only called if *convert_charrefs* is false.


.. method:: HTMLParser.handle_charref(name)

   This method is called to process decimal and hexadecimal numeric character
   references of the form :samp:`&#{NNN};` and :samp:`&#x{NNN};`.  For example, the decimal
   equivalent for ``&gt;`` is ``&#62;``, whereas the hexadecimal is ``&#x3E;``;
   in this case the method will receive ``'62'`` or ``'x3E'``.
   This method is only called if *convert_charrefs* is false.


.. method:: HTMLParser.handle_comment(data)

   This method is called when a comment is encountered (e.g. ``<!--comment-->``).

   For example, the comment ``<!-- comment -->`` will cause this method to be
   called with the argument ``' comment '``.

   The content of Internet Explorer conditional comments (condcoms) will also be
   sent to this method, so, for ``<!--[if IE 9]>IE9-specific content<![endif]-->``,
   this method will receive ``'[if IE 9]>IE9-specific content<![endif]'``.


.. method:: HTMLParser.handle_decl(decl)

   This method is called to handle an HTML doctype declaration (e.g.
   ``<!DOCTYPE html>``).

   The *decl* parameter will be the entire contents of the declaration inside
   the ``<!...>`` markup (e.g. ``'DOCTYPE html'``).


.. method:: HTMLParser.handle_pi(data)

   Method called when a processing instruction is encountered.  The *data*
   parameter will contain the entire processing instruction. For example, for the
   processing instruction ``<?proc color='red'>``, this method would be called as
   ``handle_pi("proc color='red'")``.  It is intended to be overridden by a derived
   class; the base class implementation does nothing.

   .. note::

      The :class:`HTMLParser` class uses the SGML syntactic rules for processing
      instructions.  An XHTML processing instruction using the trailing ``'?'`` will
      cause the ``'?'`` to be included in *data*.


.. method:: HTMLParser.unknown_decl(data)

   This method is called when an unrecognized declaration is read by the parser.

   The *data* parameter will be the entire contents of the declaration inside
   the ``<![...]>`` markup.  It is sometimes useful to be overridden by a
   derived class.  The base class implementation does nothing.


.. _htmlparser-examples:

Examples
--------

The following class implements a parser that will be used to illustrate more
examples:

.. testcode::

   from html.parser import HTMLParser
   from html.entities import name2codepoint

   class MyHTMLParser(HTMLParser):
       def handle_starttag(self, tag, attrs):
           print("Start tag:", tag)
           for attr in attrs:
               print("     attr:", attr)

       def handle_endtag(self, tag):
           print("End tag  :", tag)

       def handle_data(self, data):
           print("Data     :", data)

       def handle_comment(self, data):
           print("Comment  :", data)

       def handle_entityref(self, name):
           c = chr(name2codepoint[name])
           print("Named ent:", c)

       def handle_charref(self, name):
           if name.startswith('x'):
               c = chr(int(name[1:], 16))
           else:
               c = chr(int(name))
           print("Num ent  :", c)

       def handle_decl(self, data):
           print("Decl     :", data)

   parser = MyHTMLParser()

Parsing a doctype:

.. doctest::

   >>> parser.feed('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
   ...             '"http://www.w3.org/TR/html4/strict.dtd">')
   Decl     : DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"

Parsing an element with a few attributes and a title:

.. doctest::

   >>> parser.feed('<img src="python-logo.png" alt="The Python logo">')
   Start tag: img
        attr: ('src', 'python-logo.png')
        attr: ('alt', 'The Python logo')
   >>>
   >>> parser.feed('<h1>Python</h1>')
   Start tag: h1
   Data     : Python
   End tag  : h1

The content of elements like ``script`` and ``style`` is returned as is,
without further parsing:

.. doctest::

   >>> parser.feed('<style type="text/css">#python { color: green }</style>')
   Start tag: style
        attr: ('type', 'text/css')
   Data     : #python { color: green }
   End tag  : style

   >>> parser.feed('<script type="text/javascript">'
   ...             'alert("<strong>hello! &#9786;</strong>");</script>')
   Start tag: script
        attr: ('type', 'text/javascript')
   Data     : alert("<strong>hello! &#9786;</strong>");
   End tag  : script

Attribute names are converted to lowercase, quotes from attribute values removed,
and ``None`` is returned as *value* for empty attributes (such as ``checked``):

.. doctest::

   >>> parser.feed("<input TYPE='checkbox' checked required='' disabled=disabled>")
   Start tag: input
        attr: ('type', 'checkbox')
        attr: ('checked', None)
        attr: ('required', '')
        attr: ('disabled', 'disabled')

Parsing comments:

.. doctest::

   >>> parser.feed('<!--a comment-->'
   ...             '<!--[if IE 9]>IE-specific content<![endif]-->')
   Comment  : a comment
   Comment  : [if IE 9]>IE-specific content<![endif]

Parsing named and numeric character references and converting them to the
correct char (note: these 3 references are all equivalent to ``'>'``):

.. doctest::

   >>> parser = MyHTMLParser()
   >>> parser.feed('&gt;&#62;&#x3E;')
   Data     : >>>

   >>> parser = MyHTMLParser(convert_charrefs=False)
   >>> parser.feed('&gt;&#62;&#x3E;')
   Named ent: >
   Num ent  : >
   Num ent  : >

Feeding incomplete chunks to :meth:`~HTMLParser.feed` works, but
:meth:`~HTMLParser.handle_data` might be called more than once
if *convert_charrefs* is false:

.. doctest::

   >>> for chunk in ['<sp', 'an>buff', 'ered', ' text</s', 'pan>']:
   ...     parser.feed(chunk)
   ...
   Start tag: span
   Data     : buff
   Data     : ered
   Data     :  text
   End tag  : span

Parsing invalid HTML (e.g. unquoted attributes) also works:

.. doctest::

   >>> parser.feed('<p><a class=link href=#main>tag soup</p ></a>')
   Start tag: p
   Start tag: a
        attr: ('class', 'link')
        attr: ('href', '#main')
   Data     : tag soup
   End tag  : p
   End tag  : a
