html.parser — Simple HTML and XHTML parser

Вихідний код: Lib/html/parser.py


Цей модуль визначає клас HTMLParser, який служить основою для аналізу текстових файлів, відформатованих у HTML (HyperText Mark-up Language) і XHTML.

class html.parser.HTMLParser(*, convert_charrefs=True)

Створіть екземпляр парсера, здатний аналізувати недійсну розмітку.

Якщо convert_charrefs має значення True (за замовчуванням), усі посилання на символи (крім тих, що містяться в елементах script/style) автоматично перетворюються на відповідні символи Unicode.

Екземпляр HTMLParser отримує дані HTML і викликає методи обробки, коли зустрічаються початкові теги, кінцеві теги, текст, коментарі та інші елементи розмітки. Користувач повинен створити підклас HTMLParser і перевизначити його методи для реалізації бажаної поведінки.

Цей синтаксичний аналізатор не перевіряє відповідність кінцевих тегів початковим тегам і не викликає обробник кінцевих тегів для елементів, які закриваються неявно шляхом закриття зовнішнього елемента.

Змінено в версії 3.4: Додано аргумент ключового слова convert_charrefs.

Змінено в версії 3.5: Значення за замовчуванням для аргументу convert_charrefs тепер True.

Приклад програми аналізатора HTML

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

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

Примусова обробка всіх буферизованих даних так, ніби за ними стоїть позначка кінця файлу. Цей метод може бути перевизначений похідним класом, щоб визначити додаткову обробку в кінці введення, але перевизначена версія завжди повинна викликати метод базового класу HTMLParser close().

HTMLParser.reset()

Скинути примірник. Втрачає всі необроблені дані. Це викликається неявно під час створення екземпляра.

HTMLParser.getpos()

Повернути поточний номер рядка та зсув.

HTMLParser.get_starttag_text()

Повертає текст останнього відкритого початкового тегу. Зазвичай це не потрібно для структурованої обробки, але може бути корисним для роботи з HTML «у розгорнутому стані» або для повторного створення вхідних даних із мінімальними змінами (можна зберегти пробіли між атрибутами тощо).

Наступні методи викликаються, коли зустрічаються дані або елементи розмітки, і вони призначені для перевизначення в підкласі. Реалізації базового класу нічого не роблять (крім handle_startendtag()):

HTMLParser.handle_starttag(tag, attrs)

Цей метод викликається для обробки початкового тегу елемента (наприклад, <div id="main">).

Аргумент тег — це назва тегу, перетворена в нижній регістр. Аргумент attrs — це список пар (ім’я, значення), що містить атрибути, що містяться в дужках <> тегу. Ім’я буде перекладено на нижній регістр, а лапки в значенні видалено, а посилання на символи та сутності замінено.

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

Усі посилання на сутності з html.entities замінюються в значеннях атрибутів.

HTMLParser.handle_endtag(tag)

Цей метод викликається для обробки кінцевого тегу елемента (наприклад, </div>).

Аргумент тег — це назва тегу, перетворена в нижній регістр.

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; (наприклад, &gt;), де name є загальним посиланням на сутність (наприклад 'gt'). Цей метод ніколи не викликається, якщо convert_charrefs має значення True.

HTMLParser.handle_charref(name)

This method is called to process decimal and hexadecimal numeric character references of the form &#NNN; and &#xNNN;. 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 never called if convert_charrefs is True.

HTMLParser.handle_comment(data)

Цей метод викликається, коли зустрічається коментар (наприклад, <!--comment-->).

Наприклад, коментар <!-- comment --> призведе до виклику цього методу з аргументом ' comment ''.

Вміст умовних коментарів Internet Explorer (condcoms) також буде надіслано цьому методу, тому для <!--[if IE 9]> IE9-специфічного вмісту <![endif]--> цей метод отримає '[if IE 9]>IE9-специфічний вміст< ![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 із використанням кінцевого '?'' призведе до включення '?'' до даних.

HTMLParser.unknown_decl(data)

Цей метод викликається, коли аналізатор читає нерозпізнану декларацію.

Параметр data буде повним вмістом оголошення всередині розмітки <![...]>. Іноді корисно бути перевизначеним похідним класом. Реалізація базового класу нічого не робить.

Приклади

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

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:

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

>>> 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 script and style elements is returned as is, without further parsing:

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

Parsing comments:

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

>>> 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 feed() works, but handle_data() might be called more than once (unless convert_charrefs is set to 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

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

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