Selenium парсинг книг: сбор данных с Litres
В этой статье мы рассмотрим пример парсера на Selenium для сбора данных о книгах с сайта Litres. Скрипт автоматически загружает популярные книги, нажимая кнопку «Показать ещё», собирает информацию о названии, авторе, рейтинге, цене и ссылке, а затем сохраняет её в HTML-таблицу с красивым оформлением. Этот пример полезен для мониторинга книжных каталогов, анализа цен или создания персонализированных списков книг.
Для чего можно использовать этот пример?
Этот код подходит для следующих задач:
- Мониторинг книжных каталогов: Сбор данных о популярных книгах, ценах и рейтингах.
- Анализ данных: Извлечение информации для сравнения или исследований.
- Создание отчётов: Генерация HTML-таблиц для удобного просмотра.
- Обучение Selenium: Практика работы с динамическими страницами и пагинацией.
Необходимые инструменты
Для работы скрипта потребуется установить Python, библиотеки Selenium и WebDriver Manager. Selenium управляет браузером, а WebDriver Manager упрощает установку ChromeDriver.
Установка необходимых библиотек.
pip install selenium webdriver-manager
Основные модули и импорты Selenium для Python
Код программы
Ниже приведён полный код с подробными комментариями, который реализует сбор данных о книгах с сайта Litres, включая динамическую подгрузку контента и сохранение в HTML-таблицу.
Основной код программы для работы с Selenium
import time # Импорт модуля time для создания пауз между действиями
from selenium import webdriver # Импорт Selenium для управления браузером
from selenium.webdriver.common.by import By # Модуль для поиска элементов по CSS/XPath
from selenium.webdriver.chrome.service import Service # Класс для управления сервисом ChromeDriver
from selenium.webdriver.support.ui import WebDriverWait # Модуль для явного ожидания
from selenium.webdriver.support import expected_conditions as EC # Условия для ожидания
from webdriver_manager.chrome import ChromeDriverManager # Автоматическая установка ChromeDriver
# Настройки скрипта
URL = "https://www.litres.ru/popular/" # URL страницы с популярными книгами
MAX_LOADS = 5 # Максимальное количество нажатий на кнопку "Показать ещё"
DELAY = 3 # Задержка (в секундах) для загрузки контента
# Вывод информации о количестве нажатий
print(f"Будет выполнено максимум {MAX_LOADS} нажатий на кнопку 'Показать ещё'")
# Инициализация браузера Chrome
options = webdriver.ChromeOptions() # Создание объекта для настройки браузера
options.add_argument("--start-maximized") # Открытие браузера в полноэкранном режиме
# Автоматическая установка ChromeDriver через WebDriver Manager
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
driver.get(URL) # Открытие целевой страницы
# Создание объекта WebDriverWait для ожидания загрузки элементов
wait = WebDriverWait(driver, 10)
# Динамическая подгрузка книг через нажатие кнопки "Показать ещё"
for i in range(MAX_LOADS):
try:
# Ожидание, пока кнопка "Показать ещё" не станет кликабельной
show_more_btn = wait.until(
EC.element_to_be_clickable((By.XPATH, "//div[contains(text(), 'Показать ещё')]"))
)
# Прокрутка к кнопке для видимости
driver.execute_script("arguments[0].scrollIntoView(true);", show_more_btn)
time.sleep(1) # Пауза для стабилизации
show_more_btn.click() # Клик по кнопке
print(f"✅ Нажали 'Показать ещё' ({i+1})")
time.sleep(DELAY) # Ожидание загрузки нового контента
except Exception:
# Если кнопка не найдена или больше нет страниц, прерываем цикл
print(f"❌ Кнопка 'Показать ещё' не найдена или больше нет страниц (после {i} нажатий)")
break
# Сбор данных о книгах
books = driver.find_elements(By.CSS_SELECTOR, "div.ArtContent-module__vj10ya__wrapper") # Поиск всех карточек книг
data = [] # Список для хранения данных
for book in books:
try:
# Извлечение названия книги
title = book.find_element(By.CSS_SELECTOR, "a[data-testid='art__title']").text.strip()
except:
title = "N/A" # Если название не найдено, используем заглушку
try:
# Извлечение имени автора
author = book.find_element(By.CSS_SELECTOR, "a[data-testid='art__authorName--link']").text.strip()
except:
author = "N/A" # Если автор не найден, используем заглушку
try:
# Извлечение рейтинга и количества оценок
rating = book.find_element(By.CSS_SELECTOR, "span[data-testid='art__ratingAvg']").text.strip().replace(',', '.')
votes = book.find_element(By.CSS_SELECTOR, "span[data-testid='art__ratingCount']").text.strip().replace(' ', '')
rating_num = float(rating) # Преобразование рейтинга в число
votes_num = int(votes) # Преобразование количества оценок в число
rating_full = f"{rating} ({votes} оценок)" # Форматированный текст рейтинга
except:
rating_num = 0.0 # Заглушка для рейтинга
votes_num = 0 # Заглушка для оценок
rating_full = "N/A" # Если рейтинг не найден
try:
# Извлечение цены
price = book.find_element(By.CSS_SELECTOR, "div[data-testid='art__finalPrice']").text.strip()
except:
price = "N/A" # Если цена не найдена
try:
# Извлечение ссылки на книгу
link = book.find_element(By.CSS_SELECTOR, "a[data-testid='art__title']").get_attribute("href")
except:
link = "N/A" # Если ссылка не найдена
# Добавление данных в список
data.append([title, author, rating_full, price, link, rating_num, votes_num])
# Закрытие браузера
driver.quit()
# Сортировка данных по рейтингу и количеству оценок (в порядке убывания)
data_sorted = sorted(data, key=lambda x: (x[5], x[6]), reverse=True)
# Сохранение данных в HTML-файл с оформлением
html_file = "litres_books.html"
with open(html_file, "w", encoding="utf-8") as f:
# Запись HTML-заголовка и стилей
f.write('''<html>
<head>
<meta charset="UTF-8">
<title>Популярные книги Litres</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; background-color: #f7f7f7; }
h2 { color: #333; }
table { border-collapse: collapse; width: 100%; background-color: #fff; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
th, td { border: 1px solid #ddd; padding: 10px; text-align: left; font-size: 14px; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
tr:hover { background-color: #e0f7fa; }
a { color: #2196F3; text-decoration: none; }
a:hover { text-decoration: underline; }
td.number { width: 50px; font-weight: bold; }
</style>
</head>
<body>
<h2>Популярные книги с Litres (отсортированы по рейтингу и количеству оценок)</h2>
<table>
<tr>
<th>#</th>
<th>Название</th>
<th>Автор</th>
<th>Рейтинг</th>
<th>Цена</th>
<th>Ссылка</th>
</tr>
''')
# Добавление данных в таблицу
for idx, row in enumerate(data_sorted, start=1):
f.write(f"<tr>")
f.write(f"<td class='number'>{idx}</td>")
f.write(f"<td>{row[0]}</td>")
f.write(f"<td>{row[1]}</td>")
f.write(f"<td>{row[2]}</td>")
f.write(f"<td>{row[3]}</td>")
f.write(f"<td><a href='{row[4]}' target='_blank'>Ссылка</a></td>")
f.write(f"</tr>")
# Завершение HTML
f.write("</table></body></html>")
# Вывод сообщения об успешном сохранении
print(f"✅ Данные сохранены: {html_file}")
Результат
Как работает скрипт?
В этом примере скрипт Selenium выполняет следующие действия:
- Инициализация браузера: Запуск Chrome с автоматической установкой драйвера.
- Динамическая подгрузка: Нажатие кнопки «Показать ещё» для загрузки большего числа книг.
- Сбор данных: Извлечение названия, автора, рейтинга, цены и ссылки для каждой книги.
- Сортировка: Упорядочивание данных по рейтингу и количеству оценок.
- Сохранение: Создание HTML-таблицы с красивым оформлением для просмотра.
Этот пример полезен для автоматизации сбора данных с книжных сайтов, анализа популярности книг и создания структурированных отчётов.
Больше примеров по парсингу на parsertools.ru/primers.
