Изучив основы скрапинга как статического, так и динамического контента, пришло время решить более комплексную задачу: многостраничный обход. Этот раздел посвящен эффективной навигации и извлечению данных с веб-сайтов, имеющих множество взаимосвязанных страниц.
Существуют два основных подхода к обходу многостраничных веб-сайтов:
- Обход на основе ссылок - следование по ссылкам между страницами
- Обход на основе карты сайта - использование файла sitemap.xml
Для обхода по карте сайта большинство веб-сайтов предоставляют файл sitemap.xml, который перечисляет все важные URL. Этот структурированный XML-файл включает:
- URL-адреса страниц
- Даты последних изменений
- Частоту изменений
- Значения приоритета
Использование карты сайта может быть более эффективным, чем обход по ссылкам, поскольку:
- Предоставляет полный список страниц заранее
- Включает метаданные о важности и актуальности страниц
- Позволяет избежать обхода ненужных страниц
- Снижает нагрузку на сервер
Но для этой главы мы сосредоточимся на обходе на основе ссылок, используя Crawlee для создания краулера для многостраничного сайта электронной коммерции. Crawlee берет на себя многие сложности веб-обхода, включая:
- Автоматическое управление очередью и дедупликация URL
- Встроенные ограничения скорости запросов и логика повторных попыток
- Настраиваемая обработка запросов и маршрутизация
- Хранение и экспорт данных
Структура сайта, который мы будем обходить, выглядит следующим образом:
Главная страница
├── Категория: Электроника
│ ├── Телефоны
│ ├── Ноутбуки
│ └── Аксессуары
├── Категория: Одежда
│ ├── Мужская
│ └── Женская
└── Рекомендуемые товары
Каждая страница товара имеет различные макеты в зависимости от категории, но нам нужно извлечь последовательную информацию:
// Пример структуры данных, которую мы хотим построить
interface ProductData {
name: string;
price: number;
rating: { score: number, count: number };
features: string[];
status: string; // В наличии, Нет в наличии и т.д.
}
interface ResultData {
categories: {
electronics: {
phones: ProductData[];
laptops: ProductData[];
accessories: ProductData[];
};
clothing: {
mens: {
shirts: ProductData[];
pants: ProductData[];
};
womens: {
dresses: ProductData[];
tops: ProductData[];
};
};
};
featured_products: FeaturedProduct[];
}
Ключевые концепции обхода с помощью Crawlee
- Управление очередью запросов
Crawlee управляет очередью автоматически, но вот как мы её настраиваем:
import { CheerioCrawler } from 'crawlee';
const crawler = new CheerioCrawler({
// Обрабатывает каждый запрос
async requestHandler({ $, request, enqueueLinks }) {
// Обработка страницы
const data = extractPageData($);
// Автоматически добавить в очередь новые URL, найденные на странице
await enqueueLinks({
selector: 'a',
baseUrl: request.loadedUrl,
});
},
// Ограничить одновременные запросы
maxConcurrency: 10,
});
- Обработка URL
Crawlee предоставляет встроенную обработку и нормализацию URL:
await crawler.run([startUrl]);
// Или с дополнительной конфигурацией:
await crawler.addRequests([{
url: startUrl,
userData: {
label: 'start',
},
}]);
- Обработка маршрутов
Распределение различных URL по определенным обработчикам:
const crawler = new CheerioCrawler({
async requestHandler({ $, request }) {
const { label } = request.userData;
switch (label) {
case 'category':
return handleCategory($);
case 'product':
return handleProduct($);
default:
return handleHomepage($);
}
},
});
- Сбор данных
Crawlee предоставляет встроенное хранилище для собранных данных:
const crawler = new CheerioCrawler({
async requestHandler({ $, pushData }) {
const productData = extractProduct($);
await pushData(productData);
},
});
Лучшие практики веб-обхода
Хотя Crawlee решает многие задачи низкого уровня, вам стоит учитывать:
-
Конфигурация
- Устанавливайте соответствующие ограничения скорости
- Настраивайте стратегии повторных попыток
- Задавайте содержательные строки user-agent
-
Обработка ошибок
- Используйте встроенную обработку ошибок Crawlee
- Реализуйте пользовательские обработчики ошибок
- Регистрируйте значимую диагностическую информацию
-
Организация данных
- Структурируйте данные последовательно
- Используйте метки запросов для маршрутизации
- Используйте функции наборов данных Crawlee
-
Управление ресурсами
- Настройте maxConcurrency соответствующим образом
- При необходимости используйте maxRequestsPerCrawl
- Контролируйте использование памяти
Задача
Ваша задача - создать краулер на основе Crawlee, который:
- Начинает с главной страницы и обнаруживает все категории товаров
- Посещает каждую страницу категории и подкатегории
- Извлекает информацию о товарах из каждого списка
- Организует данные в структурированный формат
- Обрабатывает товары, которые появляются в нескольких местах (например, в рекомендуемых и в категории)
Сайт содержит примерно 25-30 товаров в разных категориях, с различными макетами и структурами информации. Ваш краулер должен создать комплексный набор данных, который сохраняет иерархические отношения между категориями и товарами.
Тестирование вашего решения
Проверьте:
- Полноту: Нашли ли вы все товары?
- Точность: Верны ли извлеченные данные?
- Структуру: Правильно ли организованы данные?
- Эффективность: Сколько запросов вы сделали?
Реализованный пример в _solved/chapter6/
предоставляет эталонную реализацию с использованием Crawlee. Изучите его, чтобы понять, как использовать функции библиотеки для эффективного многостраничного обхода и организации данных.
Удачного обхода!