Введение в Python (Красота) - страница 28

HTML парсер на Python


Published: 08 April 2015


Учитывая современное развитие Интернета, было бы кощунством не написать приложение, взаимодействующее со всемирной паутиной. Сегодня мы напишем простенький html-парсер на Python. Наше приложение будет читать код указанной страницы сайта и сохранять все ссылки в ней в отдельный файл. Это приложение может помочь SEO-аналитикам и веб-разработчикам.

Писать будем на Python 3, в котором есть встроенный класс для html-парсера из модуля html.parser


>| from html.parser import HTMLParser


Так же нам понадобится функция urlopen из модуля urllib


>| from urllib.request import urlopen


Именно функция urlopen будет получать исходный код указанной странички.

Перегрузка класса HTMLParser

Наша задача таким образом перегрузить функционал существующего класса HTMLParser, чтобы он соответствовал нашей задаче.


>| class MyHTMLParser(HTMLParser):

>| def __init__(self, site_name, * args, * * kwargs):

>| # список ссылок

>| self.links = []

>| # имя сайта

>| self.site_name = site_name

>| # вызываем __init__ родителя

>| super().__init__( * args, * * kwargs)

>| # при инициализации "скармливаем" парсеру содержимое страницы

>| self.feed(self.read_site_content())

>| # записываем список ссылок в файл

> self.write_to_file()


Базовый класс HTMLParser имеет несколько методов, нас в данном случае интересуют метод handle_start_tag. Этот метод вызывается каждый раз, когда наш парсер встречает в тексте октрывающий html-тэг.


>| def handle_starttag(self, tag, attrs):

>| # проверяем является ли тэг тэгом ссылки

>| if tag == 'a':

>| # находим аттрибут адреса ссылки

>| for attr in attrs:

>| if attr[0] = = 'href':

>| # проверяем эту ссылку методом validate() (мы его еще напишем)

>| if not self.validate(attr[0]):

>| # вставляем адрес в список ссылок

> self.links.append(attr[1])


Напишем вспомогательный метод validate:


>| def validate(self, link):

>| """ Функция проверяет стоит ли добавлять ссылку в список адресов.

>| В список адресов стоит добавлять если ссылка:

>| 1) Еще не в списке ссылок

>| 2) Не вызывает javascript-код

>| 3) Не ведет к какой-либо метке. (Не содержит #)

>| """

> return link in self.links or'#'inlink or'javascript:' inlink


Создадим метод, который будет открывать указанную страницу и выдавать ее содержимое.

> def read_site_content(self):

> return str(urlopen(self.site_name).read())


Осталось добавить возможность записи списка ссылок на диск в читабельном формате:


>| def write_to_file(self):

>| # открываем файл

>| f =open('links.txt', 'w')

>| # записываем отсортированный список ссылок, каждая с новой строки