Beautiful Soup парсинг: простой разбор HTML

Beautiful Soup — библиотека для разбора HTML/XML в Python. Когда её хватает, как связать с requests и когда нужен Scrapy или Playwright.

← Все статьи

beautifulsoup парсинг

Beautifulsoup парсинг — разбор уже полученного HTML (или XML) в дерево элементов на Python. Библиотека Beautiful Soup (bs4) не ходит в сеть сама: её комбинируют с requests/httpx. Это лучший старт для статичных страниц и прототипов. Большой краул — Scrapy; JS-контент — Playwright. Ниже — сценарии, код карточки товара и таблицы выбора.

beautifulsoup парсинг

Кратко

  • Beautiful Soup парсит HTML/XML; загрузку страницы делает HTTP-клиент.
  • Идеален для небольших скриптов, разовых выгрузок и обучения селекторам.
  • С парсером lxml разбор быстрее встроенного html.parser.
  • Не рендерит JavaScript и не управляет очередью URL как фреймворк.
  • Ломается при смене вёрстки — нужны тесты селекторов и мониторинг.
beautifulsoup парсинг

Инфографика: HTML-документ → дерево узлов → структурированные поля (title, price и т.д.). BS4 — слой извлечения, не краулер.

Что делает Beautiful Soup

Библиотека строит дерево документа и даёт поиск по тегам, CSS-селекторам и навигации parent/children. Это слой извлечения полей. Прокси, капчи, расписание и БД — ваша обвязка или более тяжёлый стек. На «грязном» HTML обычно ставят lxml как парсер движка.

Перед выбором BS4 откройте исходный HTML и вкладку Network: часто данные уже в JSON API, и парсить вёрстку не нужно.

Типовые задачи

ЗадачаПодходСложностьКогда не подходит
Разобрать 1–50 статичных страницhttpx + bs4НизкаяНужен регулярный краул на 100k URL
Вытащить таблицу/карточки из SSRCSS-селекторы + нормализацияНизкаяПустой #app после JS
Прототип перед ScrapyСкрипт → потом перенос селекторовНизкаяСразу нужна очередь/ретраи
Парсинг после скачивания дампаopen(file) + BeautifulSoupНизкая

Пример кода: карточка товара

import httpx
from bs4 import BeautifulSoup

URL = "https://example.com/product/demo"

def parse_product(url: str) -> dict:
    # Уважайте robots.txt и ToS; добавьте задержку в цикле
    r = httpx.get(url, timeout=20.0, headers={"User-Agent": "ResearchBot/1.0"})
    r.raise_for_status()
    soup = BeautifulSoup(r.text, "lxml")

    return {
        "url": url,
        "title": (soup.select_one("h1") or soup.title).get_text(strip=True),
        "price": (soup.select_one(".price") or soup.select_one("[itemprop=price]")).get_text(strip=True)
            if soup.select_one(".price") or soup.select_one("[itemprop=price]") else None,
        "sku": (el.get_text(strip=True) if (el := soup.select_one(".sku")) else None),
    }

if __name__ == "__main__":
    print(parse_product(URL))

Когда подходит

  1. Страница отдаёт данные в HTML без обязательного JS-рендера.
  2. Объём небольшой или средний, логика — один скрипт.
  3. Нужен быстрый прототип перед Scrapy/облаком.
  4. Команда уже на Python и хочет минимум инфраструктуры.
  5. Есть стабильные CSS/XPath-якоря в разметке.

Сравнение

КритерийBeautiful SoupScrapyCheerio
ЯзыкPythonPythonNode.js
СетьВнешний клиентВ фреймворкеВнешний клиент
Масштаб краулаСкриптФреймворкСкрипт / обвязка
Порог входаНизкийВышеНизкий для JS
JS-рендерНетЧерез плагиныНет

Ограничения и риски

«BS4 не видит» данные SPA — типичная ошибка ожидания. Уважайте ToS и robots.txt. Для регулярного мониторинга цен чаще нужен контур со SLA — парсинг интернет-магазина.

Когда не подходит

Не масштабируйте голый цикл for+httpx+BS4 на сотни тысяч URL без очереди — лучше Scrapy. Для браузерных сценариев — Playwright. Для no-code — Octoparse / ParseHub.

FAQ

Beautifulsoup или Beautiful Soup?

Официальное имя — Beautiful Soup; pip-пакет — beautifulsoup4 (bs4).

Нужен ли lxml?

Не обязателен, но рекомендуется для скорости и устойчивости.

Чем заменить на Node?

Cheerio.

Кастомный парсинг: парсинг сайтов. Серия: Scrapy, Playwright.