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 также будет отправлено этому методу, поэтому, для
<!--[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()
Парсинг doctype:
>>> 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
