BeautifulSoup — популярная библиотека Python для разбора HTML. Она хорошо подходит для страниц, где нужные данные уже есть в коде, и работает в паре с библиотекой requests. В статье — полный рабочий пример и советы, как сделать парсер стабильным.
Установка
pip install requests beautifulsoup4 lxml
Пакет lxml необязателен, но ускоряет разбор и лучше справляется с «неидеальной» разметкой.
Минимальный пример
import requests
from bs4 import BeautifulSoup
url = "https://example.com/catalog"
headers = {"User-Agent": "Mozilla/5.0 (compatible; MyParser/1.0)"}
resp = requests.get(url, headers=headers, timeout=20)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "lxml")
for card in soup.select("div.product-card"):
title = card.select_one("a.title").get_text(strip=True)
price = card.select_one("span.price").get_text(strip=True)
link = card.select_one("a.title")["href"]
print(title, price, link)
Как выбирать элементы
select() и select_one() принимают CSS-селекторы: .price, div.card a, [data-id].find() и find_all() ищут по названию тега и атрибутам.get_text(strip=True) возвращает чистый текст, tag["href"] — значение атрибута.
Селектор удобно проверять в браузере: нажмите F12, кликните правой кнопкой на элементе и выберите Copy → Copy selector.
Обход нескольких страниц
import time
rows = []
for page in range(1, 6):
resp = requests.get(f"https://example.com/catalog?page={page}", headers=headers, timeout=20)
soup = BeautifulSoup(resp.text, "lxml")
for card in soup.select("div.product-card"):
rows.append({
"title": card.select_one("a.title").get_text(strip=True),
"price": card.select_one("span.price").get_text(strip=True),
})
time.sleep(1.5)
Сохранение в CSV
import csv
with open("products.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=["title", "price"])
writer.writeheader()
writer.writerows(rows)
Кодировка utf-8-sig позволяет открыть файл в Excel без «кракозябр».
Как сделать парсер надёжнее
- Проверяйте, найден ли элемент, прежде чем брать из него текст:
if el:. - Добавьте
timeout и повторные попытки при сетевых ошибках. - Делайте паузы между запросами и не отправляйте их параллельно сотнями.
- Используйте сессию
requests.Session(), чтобы сохранять cookie и ускорить работу.
Когда BeautifulSoup не поможет
Если в ответе сервера нет нужных данных, потому что они загружаются скриптами, нужен браузер: см. парсинг динамических страниц на Python. Для страниц за логином — парсинг с авторизацией.
Не хотите тратить время на код? Разработаем парсер под вашу задачу: заказать парсер на Python, или воспользуйтесь услугой парсинг сайтов.