Найти в Дзене
programmer's notes (python and more)

Программирование на языке Python. Библиотека BeautifulSoup для разбора html-страниц

Доброго времени суток, читатели, зрители моего канала programmer's notes. Не забывайте подписываться и писать свои комментарии к моим статьям и видео.

Использование библиотеки BeautifulSoup для парсинга html-страниц

Нам уже приходилось разбирать html-страницу. Мы использовали библиотеку html.parser. Сегодня рассмотрим библиотеку BeautifulSoup, которая просто идеально подходит для работы с html.

Компоненты библиотеки устанавливаются командами (для Windows просто pip)

pip3 install lxml
pip3 install bs4

Для парсинга html-страницы нужно считать содержимое страницы в переменную, а затем создать объект BeautifulSoup

soup = BeautifulSoup(cnt, 'lxml')

Здесь мы явно указали 'lxml' - библиотеку парсинга, которую мы будем использовать. Замечу, что есть и другие парсеры, например "html5lib" или "lxml-xml" - для xml-структуры. Можно кстати использовать и стандартный python'овский парсер "html.parser". В дальнейшем в статье буду использовать парсер 'lxml'.

Замечание
Отмечу, что структура
html-файла не всегда может соотвествовать стандартам и разные парсеры будут работать с этим по-разному.

Создав объект класса мы получаем большое количество метода и свойств, позволяющих разбирать структуру html, которая была преобразована в иерархию объектов.

Основной элемент страницы это тег. У тега есть атрибуту и текст внутри тега. Также на странице могут быть ещё комментарии, но я не буду к ним обращаться.

Что можно получить, если вы создали объект: soup = BeautifulSoup(cnt, 'lxml')? Да информацию о любом теге. Например тег заголовка страницы

print(soup.title)

или только один заголовок

print(soup.title.string)

Если мы укажем тег, которых несколько на странице, то мы получим первый по счёту тег:

print(soup.meta)

или

print(soup.meta.attrs)

и мы получаем словарик атрибутов тега meta, например

{'http-equiv': 'Content-Type', 'content': 'text/html; charset=UTF-8'}

соответственно мы можем перебрать все атрибуты тега.

Для просмотра всех тегов страницы можно воспользовать одним из двух способов. Ниже представлен рекурсивный способ поиска всех тегов с именем span.

Программа обхода по тегам. Текст программы см. ниже по ссылке
Программа обхода по тегам. Текст программы см. ниже по ссылке
primer267.py

Для рекурсивного поиска по тегам страницы мы использовали метод recursiveChildGenerator(), который возвращает объект-итератор. Свойтсво name тега возвращает имя тега.

Дале представлен другой способ по тегам страницы.

Программа обхода по тегам, вариант 2. Текст программы см. ниже по ссылке
Программа обхода по тегам, вариант 2. Текст программы см. ниже по ссылке
primer268.py

Метод find_all('span') класса BeautifulSoup возращает итератор на все теги с именем span. Если не указывать параметр, то мы получим множество всех тегов, которые мы уже можем выбирать по имени, атрибутам или содержанию.

Ниже программа выдаёт все ссылки, содержащие в тегах a.

Пример получения всех ссылок на странице. Текст программы см. по ссылке
Пример получения всех ссылок на странице. Текст программы см. по ссылке
primer269.py

С помощью метода get() объекта - тег мы получаем соответствующий атрибут.

Ниже программа получает атрибут, содержащий кодировку html-страницы.

Получение атрибутов тега. Текст программы см. ниже по ссылке
Получение атрибутов тега. Текст программы см. ниже по ссылке
primer270.py

Напоминаю, что attrs - это словарь и мы, соотвественно работаем с ним как со словарём: перебор по ключам с поиском в содержимом элементов словаря. Результат выполнения программы

text/html; charset=UTF-8

Далее представлена программа с посиком на странице по идентификатору

Поиск по идентификатору. Текст программы см. ниже по ссылке
Поиск по идентификатору. Текст программы см. ниже по ссылке
primer271.py

Идентификатор тега это один из его атрибутов, вот и всё. Результат работы программы, например, такой

<div class="banner js-banner" data-config-name="240x400" id="240x400_2"></div>

До сих пор поиск по странице html осуществляся так сказать сврху-вниз. Но возможен и обратный ход. Для этого есть свойтсво parent.

Например

print(soup.title.parent.name)

и мы получим имя

head

А так

print(soup.title.parent.parent.name)

Получим

html

Ниже в программе приводится пример поиска по тегам с указанием родительских тегов.

Родительские теги. Текст программы см. ниже по ссылке
Родительские теги. Текст программы см. ниже по ссылке
primer272.py

Конечно, движение снизу вверх можно продолжать и так до тега html.

Ниже программа даёт теги ссылок и имена родительских тегов.

Пример тегов ссылок с указанием названий родительских тегов. Текст программы см. ниже по ссылке
Пример тегов ссылок с указанием названий родительских тегов. Текст программы см. ниже по ссылке
primer273.py

Наконец в программе ниже показан поиски внутри тегов, в частности взяты теги img.

Пример поиска внутри тегов. Текст программы см. ниже по ссылке
Пример поиска внутри тегов. Текст программы см. ниже по ссылке
primer274.py

Фрагмент выполнения программы

<img src="./1_files/collect_teaser" style="display: none; width: 1px; height: 1px;"/>
src ./1_files/collect_teaser
style display: none; width: 1px; height: 1px;
<img src="./1_files/collect" style="display: none; width: 1px; height: 1px;"/>
src ./1_files/collect
style display: none; width: 1px; height: 1px;
<img src="./1_files/collect_teaser(1)" style="display: none; width: 1px; height: 1px;"/>
src ./1_files/collect_teaser(1)
style display: none; width: 1px; height: 1px;

В своей статье я не стал касаться такого вопроса, как программное изменение html-страницы. Ну в другой раз.

Ну, пока всё!

Пишите свои предложения и замечания, и занимайтесь программированием, а также проектированием баз данных, хотя бы для поддержания уровня интеллекта.

Кто любит суп, а кто котлеты
Кто любит суп, а кто котлеты