html.parser — Простой парсер HTML и XHTML
Исходный код: Lib/html/parser.py
В этом модуле определён класс HTMLParser, который служит основой для парсинга текстовых файлов, отформатированных в HTML (HyperText Mark-up Language) и XHTML.
-
class html.parser.HTMLParser(*, convert_charrefs=True) -
Создаёт экземпляр парсера, способного анализировать некорректный разметку.
Если convert_charrefs равно
True(по умолчанию), все ссылки на символы (за исключением тех, которые находятся в элементахscript/style) автоматически преобразуются в соответствующие символы Юникода.Экземпляр
HTMLParserполучает данные HTML и вызывает методы обработчиков при обнаружении открывающих тегов, закрывающих тегов, текста, комментариев и других элементов разметки. Пользователь должен унаследовать от классаHTMLParserи переопределить его методы для реализации желаемого поведения.Этот парсер не проверяет, соответствуют ли закрывающие теги открывающим, или вызывает обработчик закрывающего тега для элементов, которые неявно закрываются закрытием внешнего элемента.
Изменено в версии 3.4: Добавлен ключевой аргумент convert_charrefs.
Изменено в версии 3.5: Значение по умолчанию для аргумента convert_charrefs теперь равно
True.
Пример приложения HTML-парсера
В качестве основного примера ниже представлен простой HTML-парсер, который использует класс 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
Экземпляры HTMLParser имеют следующие методы:
-
HTMLParser.feed(data) -
Передает некоторое текст в парсер. Он обрабатывается по мере того, как он состоит из полных элементов; неполные данные буферизуются до тех пор, пока не будет передано больше данных или вызван метод
close(). data должен бытьstr.
-
HTMLParser.close() -
Принудительно обрабатывает все буферизованные данные так, как будто за ними следует маркер конца файла. Этот метод может быть переопределен производным классом для определения дополнительной обработки в конце входных данных, но переопределённая версия всегда должна вызывать базовый метод класса
HTMLParserclose().
-
HTMLParser.reset() -
Сбрасывает экземпляр. Потеряет все необработанные данные. Вызывается неявно при создании экземпляра.
-
HTMLParser.getpos() -
Возвращает текущий номер строки и смещение.
-
HTMLParser.get_starttag_text() -
Возвращает текст последнего открытого тега. Обычно это не требуется для структурированной обработки, но может быть полезно при работе с HTML «как развернутым» или для повторного генерации входных данных с минимальными изменениями (можно сохранить пробелы между атрибутами и т. д.).
Следующие методы вызываются при обнаружении данных или элементов разметки и должны быть переопределены в подклассе. Реализации базового класса ничего не делают (кроме handle_startendtag()):
-
HTMLParser.handle_starttag(tag, attrs) -
Этот метод вызывается для обработки открывающего тега элемента (например,
<div id="main">).Аргумент tag — это имя тега, преобразованное в нижний регистр. Аргумент attrs — список пар
(name, value)атрибутов, найденных внутри квадратных скобок тега. Имя name будет переведено в нижний регистр, кавычки в value удалены, ссылки на символы и сущности заменены.Например, для тега
<A HREF="https://www.cwi.nl/">, этот метод будет вызван какhandle_starttag('a', [('href', 'https://www.cwi.nl/')]).Все ссылки на сущности из
html.entitiesзаменяются в значениях атрибутов.
-
HTMLParser.handle_endtag(tag) -
Этот метод вызывается для обработки закрывающего тега элемента (например,
</div>).Аргумент tag — это имя тега, преобразованное в нижний регистр.
-
HTMLParser.handle_startendtag(tag, attrs) -
Аналогично
handle_starttag(), но вызывается, когда парсер сталкивается со стилизованным пустым тегом XHTML (<img ... />). Этот метод можно переопределить для подклассов, которые требуют этой специфической лексической информации; по умолчанию просто вызываютсяhandle_starttag()иhandle_endtag().
-
HTMLParser.handle_data(data) -
Этот метод вызывается для обработки произвольных данных (например, текстовых узлов и содержимого
<script>...</script>и<style>...</style>).
-
HTMLParser.handle_entityref(name) -
Этот метод вызывается для обработки ссылки на символ с именем в формате
&name;(например,>), где name — это общая ссылка на сущность (например,'gt'). Этот метод никогда не вызывается, если convert_charrefs равноTrue.
-
HTMLParser.handle_charref(name) -
Этот метод вызывается для обработки десятичных и шестнадцатеричных числовых ссылок на символы в формате
&#NNN;и&#xNNN;. Например, десятичный эквивалент>равен>, а шестнадцатеричный —>; в этом случае метод получит'62'или'x3E'. Этот метод никогда не вызывается, если convert_charrefs равноTrue.
-
HTMLParser.handle_comment(data) -
Этот метод вызывается при обнаружении комментария (например,
<!--comment-->).Например, комментарий
<!-- comment -->вызовет этот метод с аргументом' comment '.Содержимое условных комментариев Internet Explorer (condcoms) также будет отправлено в этот метод, поэтому для
<!--[if IE 9]>IE9-specific content<![endif]-->, этот метод получит'[if IE 9]>IE9-specific content<![endif]'.
-
HTMLParser.handle_decl(decl) -
Этот метод вызывается для обработки объявления типа документа HTML (например,
<!DOCTYPE html>).Параметр decl будет содержать все содержимое объявления внутри
<!...>разметки (например,'DOCTYPE html').
-
HTMLParser.handle_pi(data) -
Метод, вызываемый при обнаружении инструкции обработки. Параметр data будет содержать всю инструкцию обработки. Например, для инструкции обработки
<?proc color='red'>, этот метод будет вызван какhandle_pi("proc color='red'"). Он предназначен для переопределения производным классом; реализация базового класса ничего не делает.Примечание
Класс
HTMLParserиспользует правила синтаксиса SGML для обработки инструкций. Инструкция обработки XHTML с использованием завершающего'?'приведет к включению'?'в data.
-
HTMLParser.unknown_decl(data) -
Этот метод вызывается, когда парсер считывает нераспознанное объявление.
Параметр data будет содержать всё содержимое объявления внутри
<![...]>разметки. Иногда полезно переопределять производным классом. Реализация базового класса ничего не делает.
Примеры
Следующий класс реализует парсер, который будет использован для иллюстрации дополнительных примеров:
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()
Парсинг объявления типа документа:
>>> 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"
Парсинг элемента с несколькими атрибутами и заголовком:
>>> 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
Содержимое элементов script и 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
>>> 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
Парсинг комментариев:
>>> parser.feed('<!-- a comment -->'
... '<!--[if IE 9]>IE-specific content<![endif]-->')
Comment : a comment
Comment : [if IE 9]>IE-specific content<![endif]
Парсинг именованных и числовых ссылок на символы и их преобразование в соответствующий символ (обратите внимание: эти 3 ссылки эквивалентны '>'):
>>> parser.feed('>>>')
Named ent: >
Num ent : >
Num ent : >
Передача неполных частей в feed() работает, но 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
© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/library/html.parser.html