BeautifulSoup: примеры (PYTHON)

Использование BeautifulSoup для парсинга веб-страниц в Python
Раздел: Парсинг HTML/XML, Веб-скрапинг
BeautifulSoup(markup: str, features: str): BeautifulSoup object

Основы функции BeautifulSoup

BeautifulSoup является конструктором основного класса библиотеки Beautiful Soup, предназначенной для извлечения данных из HTML и XML документов. Функция создает объект разбора, который представляет документ в виде иерархической структуры тегов.

Когда используется

BeautifulSoup применяется при необходимости извлечения, фильтрации или модификации данных из HTML/XML документов. Типичные сценарии использования включают веб-скрапинг, обработку RSS-лент, анализ конфигурационных файлов в XML формате и преобразование разметки.

Аргументы функции

BeautifulSoup(markup, features, builder, parse_only, from_encoding, exclude_encodings)

markup - строка или файловый объект, содержащий разметку для анализа. Обязательный параметр.

features - указание парсера для использования. Может быть строкой ('html.parser', 'lxml', 'html5lib') или списком строк. По умолчанию используется встроенный 'html.parser'.

builder - устаревший параметр, заменен features.

parse_only - объект SoupStrainer, ограничивающий часть документа для разбора.

from_encoding - кодировка строки, если она известна.

exclude_encodings - список кодировок, которые не стоит пробовать при обнаружении кодировки документа.

Возвращаемое значение

Функция возвращает объект BeautifulSoup, который представляет весь документ как древовидную структуру. Этот объект поддерживает методы навигации по дереву, поиска и модификации элементов.

Базовые примеры использования

Пример 1: Простой разбор HTML

from bs4 import BeautifulSoup

html_doc = """

  Пример страницы
  
    

Первый абзац

Второй абзац

""" soup = BeautifulSoup(html_doc, 'html.parser') print(soup.prettify())
<html>
 <head>
  <title>
   Пример страницы
  </title>
 </head>
 <body>
  <p class="first">
   Первый абзац
  </p>
  <p class="second">
   Второй абзац
  </p>
 </body>
</html>

Пример 2: Использование различных парсеров

# С использованием lxml (требует установки)
soup_lxml = BeautifulSoup(html_doc, 'lxml')

# С использованием html5lib (требует установки)
soup_html5lib = BeautifulSoup(html_doc, 'html5lib')

print(type(soup_lxml))  # <class 'bs4.BeautifulSoup'>
print(type(soup_html5lib))  # <class 'bs4.BeautifulSoup'>

Пример 3: Ограничение области разбора

from bs4 import SoupStrainer

parse_only = SoupStrainer('p', class_='first')
soup = BeautifulSoup(html_doc, 'html.parser', parse_only=parse_only)
print(soup)
<p class="first">Первый абзац</p>

Альтернативные библиотеки парсинга в Python

lxml

Библиотека lxml предоставляет высокопроизводительные инструменты для обработки XML и HTML. Основана на библиотеках libxml2 и libxslt. Отличается высокой скоростью работы и поддержкой XPath 1.0.

html5lib

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

xml.etree.ElementTree

Встроенный модуль Python для работы с XML. Поддерживает ограниченный набор функций для HTML, но эффективен для простых задач парсинга XML.

Выбор библиотеки

BeautifulSoup с парсером 'html.parser' подходит для простых задач без дополнительных зависимостей. Для высокой производительности выбирают lxml. html5lib применяют для сложных или некорректных HTML документов.

Аналоги BeautifulSoup в других языках программирования

JavaScript: Cheerio

const cheerio = require('cheerio');
const html = '
Text
'; const $ = cheerio.load(html); console.log($('.container').text());
Text

PHP: Simple HTML DOM Parser

include_once('simple_html_dom.php');
$html = str_get_html('
Content
'); echo $html->find('div.test', 0)->innertext;
Content

Java: JSoup

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

String html = "
Example
"; Document doc = Jsoup.parse(html); System.out.println(doc.text());
Example

Go: goquery

import "github.com/PuerkitoBio/goquery"

doc, _ := goquery.NewDocumentFromReader(strings.NewReader(html))
doc.Find("div").Each(func(i int, s *goquery.Selection) {
    fmt.Println(s.Text())
})

Типичные ошибки при использовании

Ошибка 1: Отсутствие парсера

# Если lxml не установлен
soup = BeautifulSoup(html_doc, 'lxml')
FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml.

Ошибка 2: Некорректная кодировка

# Документ в кодировке windows-1251, но передается как строка
html = 'Текст'
UnicodeDecodeError: 'utf-8' codec can't decode byte...

Ошибка 3: Изменение объекта во время итерации

soup = BeautifulSoup('
1
2
', 'html.parser') for div in soup.find_all('div'): div.decompose() # Модификация во время итерации
RuntimeError: dictionary changed size during iteration

Изменения в последних версиях

Beautiful Soup 4.12.0

Добавлена поддержка Python 3.12. Улучшена обработка SVG элементов. Введены новые методы для работы с пространствами имен XML.

Beautiful Soup 4.11.0

Добавлен параметр exclude_encodings в конструктор. Улучшена производительность парсинга больших документов с использованием lxml.

Beautiful Soup 4.10.0

Изменено поведение метода prettify для пустых элементов. Исправлены проблемы с кодировкой при работе с некоторыми типами документов.

Расширенные примеры использования

Пример 1: Парсинг с использованием CSS селекторов

soup = BeautifulSoup('''

''', 'html.parser')

# Поиск по CSS селектору
links = soup.select('#main a.external')
print(links[0]['href'])  # /link1

# Поиск всех элементов с классом
all_links = soup.select('.external, .internal')
print(len(all_links))  # 2

Пример 2: Работа с деревом элементов

html = '''
  • Элемент 1
  • Элемент 2 вложенный
''' soup = BeautifulSoup(html, 'html.parser') li = soup.find('li') # Навигация по дереву print(li.next_sibling) # Следующий элемент li print(li.find('span').parent) # Родительский элемент print(list(soup.ul.children)) # Все дочерние элементы

Пример 3: Модификация документа

soup = BeautifulSoup('
Текст
', 'html.parser') div = soup.div # Изменение атрибутов div['class'] = 'new' div['id'] = 'main' # Добавление нового элемента new_tag = soup.new_tag('span') new_tag.string = 'Добавлено' div.append(new_tag) print(soup.prettify())
<div class="new" id="main">
 Текст
 <span>
  Добавлено
 </span>
</div>

Пример 4: Обработка XML с пространствами имен

xml = '''<?xml version="1.0"?>

    Значение
'''

soup = BeautifulSoup(xml, 'xml')
# Поиск с учетом пространства имен
namespaced_tag = soup.find('test:elem')
print(namespaced_tag.name)  # test:elem
print(namespaced_tag.prefix)  # test

Пример 5: Потоковый парсинг больших файлов

from bs4 import SoupStrainer

# Парсим только таблицы
parse_only = SoupStrainer('table')

# Постепенная обработка большого файла
with open('large_file.html', 'r', encoding='utf-8') as f:
    for line in f:
        # Обработка фрагментами
        soup = BeautifulSoup(line, 'html.parser', parse_only=parse_only)
        if soup.table:
            process_table(soup.table)

питон BeautifulSoup function comments

En
BeautifulSoup Parse HTML/XML