Сообщить об ошибке.

Модуль html.parser в Python

Синтаксический анализатор HTML

Модуль html.parser определяет класс HTMLParser, который служит основой для парсинга файлов, отформатированных в HTML (HyperText Mark-up Language) и XHTML.

Содержание:


Базовый пример синтаксического анализа HTML.

Ниже представлен пример простого HTML парсера, который использует класс html.parser.HTMLParser, чтобы печатать начальный и конечный тэги, а так же данные между ними:

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>')

Вывод будет следующим:

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

Класс HTMLParser.

Синтаксис:

from html.parser import HTMLParser

parser = HTMLParser(*, convert_charrefs=True)

Описание:

Класс HTMLParser создает экземпляр парсера, который способен проанализировать HTML-разметку, а так же некоторую недопустимую разметку.

Если аргумент convert_charrefs имеет значение True (по умолчанию), то все ссылки на символы, такие как &gt; (кроме тех, которые содержатся в элементах script/style) автоматически преобразуются в соответствующие символы Unicode.

Экземпляр HTMLParser получает HTML-данные и вызывает соответствующие методы обработчика, когда встречаются начальные теги, конечные теги, текст, комментарии и другие элементы разметки. Пользователь должен создать подкласс HTMLParser и переопределить его методы для реализации желаемого поведения.

Синтаксический анализатор на основе класса HTMLParser не будет проверять соответствие конечных тегов начальным тегам и не будет вызывает обработчик конечных тегов для элементов, которые закрываются неявно путем закрытия внешнего элемента, например <img ... />.

Методы объекта HTMLParser.

У экземпляров HTMLParser есть следующие методы:


HTMLParser.feed(data):

Метод HTMLParser.feed() передает текст data в синтаксический анализатор. Они обрабатывается, так как состоят из полных элементов. Неполные данные буферизуются до тех пор, пока не будет подано больше данных или не будет вызван метод HTMLParser.close(). Данные data должны быть str.

HTMLParser.close():

Метод HTMLParser.close() принудительно обрабатывает все буферизованные данные, как если бы за ними следовала метка конца файла. Этот метод может быть переопределен производным классом для определения дополнительной обработки в конце ввода, но переопределенная версия всегда должна вызывать метод базового класса HTMLParser.close().

HTMLParser.reset():

Метод HTMLParser.reset() сбрасывает экземпляр на начальное состояние. Теряет все необработанные данные. Этот метод вызывается неявно во время создания экземпляра.

HTMLParser.getpos():

Метод HTMLParser.getpos() возвращает номер текущей строки и смещение.

HTMLParser.get_starttag_text():

Метод HTMLParser.get_starttag_text() возвращает текст последнего открытого начального тега. Обычно это не требуется для структурированной обработки, но может быть полезно при работе с HTML в развернутом виде или для повторной генерации ввода с минимальными изменениями (можно сохранить пробелы между атрибутами и т. д.).


Внимание! Следующие методы вызываются, когда встречаются элементы данных или разметки, они предназначены для переопределения в подклассе. Реализации базового класса ничего не делают (кроме HTMLParser.handle_starttag()):

HTMLParser.handle_starttag(tag, attrs):

Метод HTMLParser.handle_starttag() метод вызывается для обработки начала тега (например, <div id="main">).

Аргумент tag - это имя тега, преобразованное в нижний регистр. Аргумент attrs представляет собой список пар (name, value), содержащих атрибуты, найденные внутри скобок тега <>. Имя тега name будет переведено в нижний регистр, кавычки в значении тега value удалены, а ссылки на HTML-сущности заменены.

Например, для тега <A HREF="https://www.cwi.nl/">, этот метод будет вызываться с аргументами handle_starttag('a', [('href', 'https://www.cwi.nl/')]).

Все ссылки на HTML-сущности из html.entities заменяются в значениях атрибутов.

HTMLParser.handle_endtag(tag):

Метод HTMLParser.handle_endtag() вызывается для обработки конечного тега элемента (например, </div>).

Аргумент tag - это имя тега, преобразованное в нижний регистр.

HTMLParser.handle_startendtag(tag, attrs):

Метод HTMLParser.handle_startendtag() ведет себя подобно методу HTMLParser.handle_starttag(), но вызывается, когда анализатор обнаруживает пустой тег в стиле XHTML (<img ... />).

Этот метод может быть переопределен подклассами, которым требуется эта конкретная лексическая информация. Реализация по умолчанию просто вызывает HTMLParser.handle_starttag() и HTMLParser.handle_endtag().

HTMLParser.handle_data(data):

Метод HTMLParser.handle_data() вызывается для обработки произвольных данных. Например, текстовых узлов и содержимого <script>...</script> и <style>...</style>.

HTMLParser.handle_entityref(name):

Метод HTMLParser.handle_entityref() вызывается для обработки именованной ссылки на символ, вида &name; (например, &gt;), где name является общей ссылкой на сущность (например, "gt").

Этот метод никогда не вызывается, если значение аргумента convert_charrefs конструктора HTMLParser установлено как True.

HTMLParser.handle_charref(name):

Метод HTMLParser.handle_charref() вызывается для обработки десятичных и шестнадцатеричных ссылок на числовые символы вида &#NNN; и &#xNNN;. Например, десятичный эквивалент для &gt; равен &#62;, тогда как шестнадцатеричный - &#x3E;. В этом случае метод получит " 62 " или "x3E".

Этот метод никогда не вызывается, если значение аргумента convert_charrefs конструктора HTMLParser установлено как True.

HTMLParser.handle_comment(data):

Метод HTMLParser.handle_comment() вызывается при обнаружении комментария (например,<! --комментарий-->).

Например, комментарий <!-- comment --> вызовет этот метод с аргументом data, равным "comment".

Содержимое условных комментариев Internet Explorer (condcoms) также будет отправлено этому методу, например для <!--[if IE 9]>IE9-specific content<![endif]-->, метод получит '[if IE 9]>IE9-specific content<![endif]'.

HTMLParser.handle_decl(decl):

Метод HTMLParser.handle_decl() вызывается для обработки объявления типа документа HTML (например, <!DOCTYPE html>).

Аргументом decl будет все содержимое объявления внутри разметки! Например, 'DOCTYPE html'.

HTMLParser.handle_pi(data):

Метод HTMLParser.handle_pi() вызываемый при обнаружении инструкции по обработке. Аргумент data будет содержать всю инструкцию по обработке.

Например, для инструкции по обработке <?proc color='красный'> этот метод будет вызываться с аргументами parser.handle_pi("proc color='красный'"). Метод предназначен для переопределения производным классом, реализация базового класса ничего не делает.

Примечание. Класс HTMLParser использует синтаксические правила SGML для обработки инструкций. Команда обработки XHTML с использованием конечного '?' приведет к включению '?' в аргумент data.

HTMLParser.unknown_decl(data):

Метод HTMLParser.unknown_decl() вызывается, когда синтаксический анализатор считывает нераспознанное объявление.

Аргумент data будет принимать все содержимое объявления внутри разметки <![...]>. Иногда бывает полезно переопределить этот метод в дочернем классе. Реализация базового класса ничего не делает.

Расширенные примеры использования парсера HTML-разметки.

Класс MyHTMLParser реализует парсер, который будет использоваться для иллюстрации дополнительных расширенных примеров:

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()

Разбор DOCTYPE:

>>> parser.feed('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">'
# Decl  : DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"

Разбор элемента с несколькими атрибутами и заголовком:

>>> 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

Содержание HTML-тегов script и элементов style, возвращается как есть, без дальнейшего анализа:

# Разбор HTML-тега `style`
>>> parser.feed('<style type="text/css">#python { color: green }</style>')
# Start tag: style
#      attr: ('type', 'text/css')
# Data     : #python { color: green }
# End tag  : style

# Разбор HTML-тега `script`
>>> parser.feed('<script type="text/javascript">alert("<strong>hello!</strong>");</script>')
# Start tag: script
#      attr: ('type', 'text/javascript')
# Data     : alert("<strong>hello!</strong>");
# End tag  : script

Разбор HTML-комментариев:

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

Разбор HTML-мнемоник и числовых ссылок на символы Юникода и преобразование их в человеческие символы (примечание: все эти 3 ссылки эквивалентны символу '>'):

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

Подача неполных фрагментов в метод parser.feed() работает, но [parser.handle_data()](#HTMLParser.handle_data) может вызываться более одного раза (если только значениеconvert_charrefs=True`):

>>> 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

Парсинг не валидной HTML-разметки также работает (например атрибуты без кавычек):

>>> 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