Python - BeautifulSoup - парсинг html - 2026

Материал из Wiki - Iphoster - the best ever hosting and support. 2005 - 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

Текст внутри тега представлен объектом 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 поддерживает несколько парсеров:

Парсеры 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
Характеристика 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-документами.

Ссылки

×
Реклама
ИКС