
Если вы когда-нибудь пытались собрать список товаров с сайта — будь то электроника, одежда или книги — вы наверняка столкивались с пагинацией: «Страница 1, 2, 3…».
Вручную копировать сотни страниц с карточками — не вариант. Но с Python это решается за 20 строк кода.
В этой статье я покажу пошагово, как
- Найти ссылку на следующую страницу
- Автоматически перелистывать все страницы
- Извлекать название, цену и URL товара
- Сохранить всё в CSV без дубликатов
Всё — на реальном демо-сайте, с объяснением каждой строки кода.
Оглавление
Выбор демо-сайта и структура пагинации
Используем официальный учебный ресурс:
👉 https://books.toscrape.com/
Там:
- Чёткая пагинация внизу страницы
- Каждый товар — карточка с названием, ценой и ссылкой
- Нет JavaScript — подходит для
requests+BeautifulSoup
URL пагинации выглядит так:
- Страница 1:
https://books.toscrape.com/ - Страница 2:
https://books.toscrape.com/catalogue/page-2.html - Страница 3:
https://books.toscrape.com/catalogue/page-3.html
💡 Но так же в некоторых случаях пагинация может быть через
?page=2— мы разберём оба подхода.
Шаг 1. Установка и подготовка
Установите зависимости
pip install requests beautifulsoup4 pandas
requests— загрузка страницbeautifulsoup4— парсинг HTMLpandas— удобное сохранение в CSV
Импорты и переменные
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import os
BASE_URL = "https://books.toscrape.com/"
Шаг 2. Парсинг одной страницы
Как найти структуру карточки товара
- Откройте сайт → ПКМ на книге → «Просмотреть код»
- Вы увидите:
<article class="product_pod">
<h3><a href="..." title="A Light in the...">A Light in the...</a></h3>
<p class="price_color">£51.77</p>
</article>
Код для извлечения данных
def parse_page(url):
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")
products = []
for item in soup.select("article.product_pod"):
title = item.h3.a["title"]
price = item.select_one("p.price_color").text
link = BASE_URL + item.h3.a["href"]
products.append({"title": title, "price": price, "link": link})
return products
📚
select()использует CSS-селекторы — самый удобный способ навигации по DOM.
Шаг 3. Определение количества страниц
Вариант 1. Через номер последней страницы
На books.toscrape.com внизу есть ссылки вида:
<li class="current">Page 1 of 17</li>
Извлекаем число:
def get_total_pages(base_url):
response = requests.get(base_url)
soup = BeautifulSoup(response.content, "html.parser")
current = soup.select_one("li.current")
if current:
text = current.text.strip()
# "Page 1 of 17" → разбиваем и берём последнее число
return int(text.split()[-1])
return 1
Вариант 2. Через отсутствие кнопки «Next»
Если на странице нет ссылки «Next» — значит, это последняя.
def has_next_page(soup):
return soup.select_one("li.next") is not None
Этот метод универсален для сайтов вроде ?page=1, ?page=2.
Шаг 4. Цикл по всем страницам
all_products = []
total_pages = get_total_pages(BASE_URL)
print(f"Всего страниц: {total_pages}")
for page in range(1, total_pages + 1):
if page == 1:
url = BASE_URL
else:
url = f"https://books.toscrape.com/catalogue/page-{page}.html"
print(f"Парсинг страницы {page}...")
products = parse_page(url)
all_products.extend(products)
# Вежливая пауза
time.sleep(1)
print(f"Всего товаров собрано: {len(all_products)}")
⚠️
time.sleep(1)— уважение к серверу. Без паузы вас могут заблокировать.
Шаг 5. Сохранение в CSV
df = pd.DataFrame(all_products)
df.to_csv("books.csv", index=False, encoding="utf-8-sig")
print("✅ Данные сохранены в books.csv")
Флаг utf-8-sig гарантирует, что кириллица откроется корректно в Excel.
Обработка ошибок и улучшения
Защита от падений
Оберните каждую страницу в try/except:
try:
products = parse_page(url)
all_products.extend(products)
except Exception as e:
print(f"Ошибка на странице {page}: {e}")
continue
Уникальность товаров
Иногда пагинация дублирует карточки. Уберите дубли по ссылке:
df = df.drop_duplicates(subset=["link"])
Адаптация под другие сайты
Если пагинация через ?page=2:
# Пример: https://shop.com/products?page=1
for page in range(1, 21): # если знаете, что максимум 20
url = f"https://shop.com/products?page={page}"
# ... парсинг
Или динамически:
page = 1
while True:
url = f"https://shop.com/products?page={page}"
response = requests.get(url)
if "Нет товаров" in response.text or response.status_code != 200:
break
# парсим
page += 1
Заключение
Надеюсь мои примеры вам помогут и сможете:
✅ Определять тип пагинации
✅ Автоматически перелистывать все страницы
✅ Извлекать данные из карточек
✅ Сохранять результат в CSV с поддержкой кириллицы
✅ Добавлять защиту от ошибок и дублей
Этот шаблон работает на любом каталоге — от маркетплейсов до новостных лент, может с небольшими правками под ваши потребности. Главное у вас есть основа!
🐍 Сохраните код — и вы сможете собирать данные с любого пагинированного сайта за минуты.
• python парсинг js сайта — сбор данных с динамических страниц через Playwright
• python парсинг таблицы html — извлечение таблиц в DataFrame
• python скачать изображения с сайта — автоматическая загрузка медиа
📢 Подписывайтесь на Telegram-канал PythonAuto, чтобы не пропустить новые гайды по автоматизации, парсингу и Python.
👉 Ваш интерес — лучшая мотивация для новых статей!