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')
>| # записываем отсортированный список ссылок, каждая с новой строки