В стандартной библиотеке Python имеется также модуль html.parser, поддерживающий анализ разметки HTML, хотя и с ограниченными возможностями, который можно использовать для извлечения информации из веб-страниц. Помимо всего прочего этот парсер можно использовать для обработки веб-страниц, получаемых с помощью модуля urllib.request, с которым мы познакомились в части книги, посвященной программированию для Интернета, для извлечения простого текста из сообщений электронной почты в формате HTML и других нужд.
Модуль html.parser имеет прикладной интерфейс, напоминающий модель XML SAX, представленную в предыдущем разделе: он предоставляет механизм синтаксического анализа, который можно наследовать в своих подклассах для перехвата событий обнаружения тегов и их содержимого, возникающих в процессе анализа. В отличие от модели SAX, мы должны не предоставлять свой класс-обработчик, а расширять класс парсера непосредственно. Ниже приводится короткий интерактивный пример, демонстрирующий основы (весь программный код для этого раздела я скопировал в файл htmlparser.py, который находится в пакете примеров, на случай, если у вас появится желание поэкспериментировать самостоятельно):
> >> from html.parser import HTMLParser
> >> class ParsePage(HTMLParser):
… def handle_starttag(self, tag, attrs):
… print(‘Tag start:’, tag, attrs)
… def handle_endtag(self, tag):
… print(‘tag end: ‘, tag)
… def handle_data(self, data):
… print(‘data.. ‘, data.rstrip())
Теперь создадим текстовую строку с разметкой HTML веб-страницы — мы жестко определяем ее здесь, но с тем же успехом ее можно загрузить из файла или получить с веб-сайта с помощью модуля urllib.request:
> >> page = """
… <html>
… <h1>Spam!</h1>
… <p>Click this <a href="http://www.python.org">python</a> link</p>
… </html>"""
Наконец, запустим анализ, передав текст экземпляру парсера, — при обнаружении тегов HTML будут вызываться методы обратного вызова, которым в качестве аргументов будут передаваться имена тегов и последовательности атрибутов:
> >> parser = ParsePage()
> >> parser.feed(page)
data…
Tag start: html []
data…
Tag start: h1 [] data Spam!
tag end: h1 data
Tag start: p [] data Click this
Tag start: a [(‘href’, ‘http://www.python.org’)] data python
tag end: a data link
tag end: p data
tag end: html
Как видите, в процессе анализа по событиям вызываются методы парсера. Как и при использовании модели SAX XML, в процессе анализа ваш класс парсера должен сохранять информацию о состоянии в своих атрибутах, если он должен делать что-то более конкретное, чем просто выводить имена тегов, атрибуты и содержимое. При этом реализация извлечения содержимого определенных тегов может состоять просто из проверки имен тегов и установки флагов состояния. Кроме того, в процессе анализа достаточно просто можно было бы реализовать конструирование дерева объектов, отражающего структуру страницы.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011