BeautifulSoup: примеры (PYTHON)
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());TextPHP: Simple HTML DOM Parser
include_once('simple_html_dom.php');
$html = str_get_html('Content');
echo $html->find('div.test', 0)->innertext;ContentJava: JSoup
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
String html = "Example";
Document doc = Jsoup.parse(html);
System.out.println(doc.text());ExampleGo: 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('12', '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)