Python - BeautifulSoup - парсинг html - 2026
Published: 2026-07-30
BeautifulSoup — это библиотека Python для извлечения данных из HTML и XML-документов. Она предоставляет идиоматические способы навигации, поиска и модификации дерева парсинга, работая поверх различных парсеров. BeautifulSoup широко используется в веб-скрапинге, автоматизации тестирования и анализе веб-контента.
На момент 2026 года актуальной является версия 4.15.x (BS4). Предыдущее поколение — BeautifulSoup 3 — официально перестало поддерживаться 31 декабря 2020 года.
Установка
Установка через pip:
pip install beautifulsoup4
Для работы с HTML-документами рекомендуется также установить один из парсеров:
pip install lxml # Самый быстрый HTML/XML-парсер pip install html5lib # Соответствует спецификации HTML5 (медленнее)
Встроенный парсер Python (html.parser) не требует отдельной установки.
Быстрый старт
from bs4 import BeautifulSoup
html = '''
<html>
<head><title>Пример</title></head>
<body>
<p class="content">Привет, мир!</p>
<a href="https://example.com">Ссылка</a>
</body>
</html>
'''
soup = BeautifulSoup(html, 'html.parser')
print(soup.title.text) # "Пример"
print(soup.find('p').text) # "Привет, мир!"
print(soup.a['href']) # "https://example.com"
Типы объектов
BeautifulSoup использует четыре основных типа объектов Python:
Tag
Объект Tag соответствует HTML- или XML-тегу. Поддерживает доступ к атрибутам через словарь:
tag = soup.a
print(tag.name) # "a"
print(tag['href']) # "https://example.com"
print(tag.attrs) # {'href': 'https://example.com'}
Текст внутри тега представлен объектом NavigableString:
tag = soup.p print(tag.string) # "Привет, мир!" print(type(tag.string)) # <class 'bs4.element.NavigableString'>
BeautifulSoup
Сам объект BeautifulSoup представляет весь документ как единое целое.
Comment
Комментарии HTML представлены специальным подклассом NavigableString:
comment = soup.find(string=lambda text: isinstance(text, Comment))
Навигация по дереву
BeautifulSoup предоставляет несколько способов перемещения по DOM-дереву.
Вниз по дереву
# Доступ к дочерним элементам soup.head.title # Цепочка атрибутов soup.body.contents # Список всех дочерних элементов soup.body.children # Итератор по дочерним элементам soup.body.descendants # Итератор по всем вложенным элементам # .string — если у тега один потомок-строка print(soup.title.string)
Вверх по дереву
# Родительский элемент tag.parent tag.parents # Итератор по всем предкам
В стороны
# Соседние элементы tag.next_sibling tag.previous_sibling tag.next_siblings # Итератор tag.previous_siblings # Итератор
Поиск во всех направлениях
# Следующий/предыдущий элемент в порядке обхода документа tag.next_element tag.previous_element tag.next_elements tag.previous_elements
Поиск по дереву
find() и find_all()
# Поиск всех тегов p
soup.find_all('p')
# Поиск с фильтром по атрибутам
soup.find_all('a', href=True)
soup.find_all('div', class_='container')
soup.find_all('span', id='price')
# Поиск первого совпадения
soup.find('h1')
Фильтры
В качестве аргументов можно передавать:
- Строку — имя тега:
find_all('p') - Регулярное выражение:
find_all(re.compile('^h[1-6]')) - Список:
find_all(['h1', 'h2', 'h3']) - True — все теги:
find_all(True) - Функцию:
find_all(lambda tag: tag.has_attr('data-id'))
CSS-селекторы
soup.select('div.container')
soup.select('#main-content')
soup.select('a[href^="https://"]')
soup.select_one('p.intro') # Первое совпадение
Продвинутый поиск по атрибутам
# Поиск по CSS-классам
soup.find_all(class_='highlight')
soup.find_all('div', class_=['foo', 'bar'])
# Поиск по произвольным атрибутам
soup.find_all(attrs={'data-price': True})
soup.find_all(attrs={'aria-label': 'Close'})
# Поиск по тексту
soup.find_all(string='Python')
soup.find_all(string=re.compile('цена'))
soup.find_all('p', string='Искомый текст')
Ограничения и пагинация
# Первые 10 результатов
soup.find_all('a', limit=10)
# Пропуск первых N результатов (через срезы)
soup.find_all('div')[10:20]
Модификация дерева
BeautifulSoup позволяет изменять HTML-документ.
Изменение тегов и атрибутов
tag = soup.find('p')
tag.name = 'div' # Изменение имени тега
tag['class'] = 'updated' # Установка атрибута
tag['id'] = 'main' # Добавление атрибута
del tag['class'] # Удаление атрибута
Изменение строк
tag.string = 'Новый текст'
tag.append(' дополнительный текст ')
Создание и вставка элементов
from bs4 import BeautifulSoup, Tag, NavigableString
new_tag = soup.new_tag('span', attrs={'class': 'highlight'})
new_tag.string = 'Новый элемент'
# Вставка в конец
tag.append(new_tag)
# Вставка перед/после
tag.insert_before(new_tag)
tag.insert_after(new_tag)
# Очистка содержимого
tag.clear()
Удаление
tag.decompose() # Удаляет тег и всех потомков tag.extract() # Удаляет тег и возвращает его
Вывод и форматирование
# Стандартный HTML-вывод
str(soup)
soup.prettify() # С отступами
# Только текст (без тегов)
soup.get_text()
soup.get_text(separator=' ', strip=True)
# Кодировки
soup.encode('utf-8')
soup.decode()
Форматировщики (formatters)
# Минимальное форматирование str(soup, formatter='minimal') # HTML-сущности str(soup, formatter='html') # Без форматирования (как есть) str(soup, formatter=None) # Пользовательский форматировщик from bs4.formatter import HTMLFormatter formatter = HTMLFormatter(entity_substitution=lambda s: s.upper()) str(soup, formatter=formatter)
Парсеры
BeautifulSoup поддерживает несколько парсеров:
| Парсер | Типичное использование | Скорость | Поддержка XML |
|---|---|---|---|
| html.parser | Встроенный Python | Средняя | Нет |
| lxml | Сторонний, рекомендуется | Высокая | Да |
| html5lib | Соответствие HTML5 | Низкая | Нет |
| xml (lxml-xml) | XML-документы | Высокая | Да |
Выбор парсера:
soup = BeautifulSoup(html, 'lxml') soup = BeautifulSoup(html, 'html5lib') soup = BeautifulSoup(html, 'xml') # Для XML
Диагностика парсера
from bs4 import diagnose
with open('page.html') as f:
diagnose(f.read())
Парсинг XML
BeautifulSoup поддерживает парсинг XML при использовании соответствующего парсера:
soup = BeautifulSoup(xml_data, 'xml') # или soup = BeautifulSoup(xml_data, 'lxml-xml')
При работе с XML доступны все те же методы навигации и поиска.
Работа с кодировками
BeautifulSoup автоматически определяет кодировку документа:
soup = BeautifulSoup(response.content, 'lxml') # Явное указание кодировки soup = BeautifulSoup(response.content, 'lxml', from_encoding='utf-8')
Для переопределения обнаруженной кодировки:
soup.original_encoding # Определённая кодировка
Работа с нестандартным HTML
BeautifulSoup отлично справляется с "грязным" HTML (malformed HTML):
- Автоматически закрывает незакрытые теги
- Исправляет неправильную вложенность
- Игнорирует некорректные символы
- Обрабатывает HTML-сущности
garbage_html = '<p>Текст<br><p>Ещё текст</p>' soup = BeautifulSoup(garbage_html, 'html.parser') print(soup.prettify())
Сравнение: BeautifulSoup 3 → 4
| Характеристика | BS3 | BS4 |
|---|---|---|
| Поддержка | Прекращена 31.12.2020 | Активная |
| Парсеры | Только sgml, html5lib | html.parser, lxml, html5lib, xml |
| Поддержка XML | Через сторонние парсеры | Нативная через lxml-xml |
| Кодировки | Ограниченная | Автоопределение, from_encoding |
| CSS-селекторы | Не поддерживаются | select(), select_one() |
| Установка | pip install BeautifulSoup | pip install beautifulsoup4 |
| Модуль | BeautifulSoup | bs4 |
Интеграция с requests
Наиболее частый сценарий — совместное использование с библиотекой requests:
import requests
from bs4 import BeautifulSoup
response = requests.get('https://example.com')
soup = BeautifulSoup(response.text, 'lxml')
# Использование заголовков
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get('https://example.com', headers=headers)
soup = BeautifulSoup(response.content, 'lxml')
Типичные сценарии использования
Сбор всех ссылок со страницы
soup = BeautifulSoup(html, 'lxml')
for link in soup.find_all('a'):
href = link.get('href')
text = link.get_text(strip=True)
if href:
print(f'{text}: {href}')
Извлечение данных из таблицы
table = soup.find('table')
for row in table.find_all('tr'):
cells = row.find_all(['td', 'th'])
print([cell.get_text(strip=True) for cell in cells])
Парсинг meta-тегов
for meta in soup.find_all('meta'):
name = meta.get('name')
content = meta.get('content')
if name and content:
print(f'{name}: {content}')
Обработка вложенных структур
items = soup.select('div.item')
for item in items:
title = item.select_one('.title').text
price = item.select_one('.price').text
link = item.select_one('a')['href']
print(f'{title}: {price} — {link}')
Производительность
| Парсер | Скорость | Потребление памяти |
|---|---|---|
| lxml | 1x (эталон) | Среднее |
| html.parser | ~4x медленнее lxml | Низкое |
| html5lib | ~20–30x медленнее lxml | Высокое |
| xml (lxml-xml) | 1x | Среднее |
Для пакетной обработки множества документов рекомендуется использовать lxml. Для однократного парсинга небольшого документа подойдёт html.parser.
Обработка ошибок
from bs4 import BeautifulSoup
from bs4 import FeatureNotFound
try:
soup = BeautifulSoup(html, 'lxml')
except FeatureNotFound:
soup = BeautifulSoup(html, 'html.parser')
Диагностика проблемных документов
from bs4 import diagnose
with open('problematic.html', 'r') as f:
diagnose(f.read())
Функция diagnose() выводит информацию о том, как каждый доступный парсер обрабатывает документ, что помогает выявить проблемы с парсингом.
Резюме
BeautifulSoup остаётся одной из самых популярных библиотек Python для парсинга HTML и XML. Ключевые преимущества:
- Простота использования: интуитивный API для навигации и поиска
- Устойчивость к "грязному" HTML: работает с невалидными документами
- Гибкость: поддержка нескольких парсеров (html.parser, lxml, html5lib)
- Поддержка CSS-селекторов: поиск элементов через select() и select_one()
- Полная поддержка XML: через парсер xml/lxml-xml
- Автоопределение кодировок: корректная обработка разных кодировок
- Активное сообщество: версия 4.15.x активно развивается и поддерживается
BeautifulSoup идеально подходит для веб-скрапинга, извлечения данных, анализа HTML-отчётов, тестирования веб-приложений и автоматизации обработки документов.
При выборе парсера рекомендуется lxml для максимальной производительности, html.parser — для минимальных зависимостей (встроен в Python), xml — для работы с XML-документами.
Ссылки
- Официальная документация BeautifulSoup
- BeautifulSoup на PyPI
- Официальный сайт BeautifulSoup
- Исходный код на GitHub
- lxml — быстрый XML/HTML-парсер
- requests — HTTP-библиотека для Python
- html.parser — встроенный парсер Python
- Группа обсуждения BeautifulSoup
- html5lib — парсер, соответствующий HTML5
- BeautifulSoup в Wikipedia
